Отношения многие ко многим

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 12:29:13

Как реализовать? Когда у первого класса свойством должна быть коллекция объектов второго класса, а у второго - свойство с коллекцией объектов первого класса?
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 28.06.2012 12:36:38

А в чем проблема?

T2Class = class;

T1Class = class
property Item[Index: Integer]: T2Class ...
...

T2Class = class
property Item[Index: Integer]: T1Class ...
...
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 12:37:24

Ах, да.... ОЧЕНЬ (вот просто люто-бешено) хочется чтобы всё было в разных модулях :-(

Добавлено спустя 19 секунд:
Когда уже в FPC будет поддержка пространств имён :-(
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение alexs » 28.06.2012 13:00:25

А кто мешает разнести по разным модулям?
Странная здача - из разряда сферических коней в вакуме...
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 13:30:24

Модуль длиннее 700 строк (эмпирическое наблюдение) меня начинает напрягать. Поэтому объединения нескольких классов в один модуль, за редким исключением, стараюсь избежать.
Код: Выделить всё

Unit UnitA;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassA = Class
  Public
    // тут должен быть класс B
End;

Implementation

End.

Код: Выделить всё

Unit UnitB;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassB = Class
  Public
    // тут должен быть класс A
End;

Implementation

End.

Как я это разнесу по разным модулям? Я знаю только костыльное полурешение с инклюдами...
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение zub » 28.06.2012 14:06:38

Такое в паскале наврятли появится, это скорее ошибка проектирования программы, чем недостаток языка.
Я обычно выкручиваюсь так
Код: Выделить всё
Unit UnitA;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassA = Class
  Public
    // тут абстрактный предок класса B с нужным функционалом
End;

Implementation

End.

Код: Выделить всё
Unit UnitB;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassB = Class
  Public
    // тут абстрактный предок класса А с нужным функционалом
End;

Implementation

End.

Правда классы плодятся как грибы, тоже не гут((
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 14:24:05

хм... спасибо ^_^
это скорее ошибка проектирования программы

Вот часто слышу такое. Но не могу понять, что ошибочного в этой идее.
Есть класс, он должен иметь список учеников. Есть ученик, которому было бы очень неплохо знать, в каком классе он учится.
Почему для такой банальной ситуации приходится изворачиваться, заносить оба (дальше - больше) класса в один исходный файл или создавать абстрактный класс... Ну неудобно же
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение zub » 28.06.2012 14:53:28

Всё не может знать о всём. Голова ученика знает где учится, ногам это знать не обязательно, они ходят туда куда скажет голова))
ИМХО всё бить на "атомарные" состовляющие и из них уже составлять нужные структуры - вполне логичный подход
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 14:56:19

но почему-то в том же C# я могу такое осуществить без особых проблем, просто поместив файлы с описанием класса и ученика в один Namespace. Сейчас попробую накидать вариант с головой, по-моему оно тоже не пройдёт ^_^

Добавлено спустя 13 минут 9 секунд:
Ну да, старый добрый unit3.pas(8,27) Fatal: Circular unit reference between Unit3 and Unit1
Unit1:
Код: Выделить всё
Unit Unit1;
Interface
Uses
  Classes, SysUtils, Unit2;
Type
TGrade = Class
  Private
    fPupils: TPupil;
  Public
    Property Pupils: TPupil Read fPupils;
End;
Implementation
End.

Unit2:
Код: Выделить всё
Unit Unit2;
Interface
Uses
  Classes, SysUtils, Unit3;
Type
TPupil = Class
  Private
    fHead: TPupilHead;
    fLegs: TPupilLegs;
  Public
    Property Head: TPupilHead Read fHead;
    Property Legs: TPupilLegs Read fLegs;
End;
Implementation
End.

Unit3:
Код: Выделить всё
Unit Unit3;
Interface
Uses
  Classes, SysUtils, Unit1;
Type
TPupilHead = Class
Private
  fGrade: TGrade;
  Public
    Property Grade: TGrade Read fGrade;
End;
Implementation
End.

Почему-то порочной считается именно сама циклическая связь между классами... Но ведь, блин, она очевидна и правильна >_<
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение zub » 28.06.2012 15:25:21

>>Но ведь, блин, она очевидна и правильна >_<
а в каком порядке юниты инициализировать? Цикличные ссылки даже если их вынести за Implementation - зло, нераз напарывался на ситуацию когда безобидная правка исходников меняла порядок инициализации юнитов, да и вообще когда всё друг на дружку ссылается в uses - подцепил "старый" модуль в новый проект, и не заметил как у тебя весь "старый" проект подцепился к новому.

Добавлено спустя 4 минуты 12 секунд:
В предидущем посте ты не избавился от цикличности, ты ее вместо 2х цацикленных модулей разнес по 3м. нужно от нее избавляться
Код: Выделить всё
Unit UnitA;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassA = Class
  Public
    // тут абстрактный предок класса B с нужным функционалом
End;

Implementation

End.

Код: Выделить всё
Unit UnitB;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils;

Type

{ ClassB }

ClassB = Class
  Public
    // тут абстрактный предок класса А с нужным функционалом
End;

Implementation

End.
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 15:43:30

в идеале хотелось бы, чтобы модули, установленные в одном Namespace, читались как один...
Что-то вроде
School:
Код: Выделить всё
Unit School;
Interface
Uses
  fgl;

Type TGrade = Class;
Type TGrades = Specialize TFPGList<TGrade>;

Type TPupil = Class;
Type TPupils = Specialize TFPGList<TPupil>;

Implementation

End.

School.Grade:
Код: Выделить всё
Unit School.Grade;
Interface
Uses
  Classes, SysUtils;
Type TGrade = Class
  Strict Private
    fPupils: TPupils;
  Public
    Property Pupils: TPupils Read fPupils;
End;
Implementation
End.

School.Pupil:
Код: Выделить всё
Unit School.Pupil;
Interface
Uses
  Classes, SysUtils;
Type TPupil = Class
  Strict Private
    fGrade: TGrade;
  Public
    Property Grade: TGrade Read fGrade;
End;
Implementation
End.

И всё. Компилятор проходя по модулям объединяет модули с точкой в названии в один "псевдо" файл. Можно ему даже помочь чем-то вроде
Код: Выделить всё
Unit School;
{$namespace school.grade}
{$namespace school.pupil}
Interface
Uses fgl;
Type TGrade = Class;
Type TGrades = Specialize TFPGList<TGrade>;
Type TPupil = Class;
Type TPupils = Specialize TFPGList<TPupil>;
Implementation
End.
объединяет так, что и Interface, и Implementation части - вначале идут из родительского класса, потом из всех остальных, без особой важности в каком порядке... И всё! И кучу всего сразу можно делать - и обращаться к приватным полям классов в одном пространстве имён, и Strict Private обретёт смысл и вообще... Классно же было бы, и удобно...
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 28.06.2012 16:04:32

Все дело в том, что ученик - это один объект, класс - это другой, а расписание или история, где он учился - это третий. Вот тогда все встает на свои места. Если бы это было в БД, то третья нормальная форма обязала бы нас сделать еще одну таблицу с двумя форейгнкеями на учеников и на классы.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 16:15:57

история это конечно круто... Но проблему, толком, не решает... А дополненная реализация namespace'ов - решила бы...
Я понимаю, если бы этого нигде не было и всегда говорили бы "фи"... Но, блин, в современных языках такое реализуется довольно просто и выгода очевидена и велика... А уж как тесты бы славно легли на такой механизм....
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Отношения многие ко многим

Сообщение stikriz » 28.06.2012 16:18:55

Это только вначале паскаль кажется ущербным. Потом понимаешь, что так оно наиболее логично. Кстати, паттерны поизучайте - меньше будет таких извратов.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Отношения многие ко многим

Сообщение Brainenjii » 28.06.2012 16:27:10

Ещё раз.
Есть класс, он должен иметь список учеников. Есть ученик, которому было бы очень неплохо знать, в каком классе он учится.
Что извращённого в желании реализовать такое? Какой анти-паттерн существует для такой структуры?
З.Ы. и 3 нормальная форма не имеет никакого отношения к озвученной проблеме
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

Рейтинг@Mail.ru