Страница 1 из 5
Отношения многие ко многим
Добавлено:
28.06.2012 12:29:13
Brainenjii
Как реализовать? Когда у первого класса свойством должна быть коллекция объектов второго класса, а у второго - свойство с коллекцией объектов первого класса?
Re: Отношения многие ко многим
Добавлено:
28.06.2012 12:36:38
stikriz
А в чем проблема?
T2Class = class;
T1Class = class
property Item[Index: Integer]: T2Class ...
...
T2Class = class
property Item[Index: Integer]: T1Class ...
...
Re: Отношения многие ко многим
Добавлено:
28.06.2012 12:37:24
Brainenjii
Ах, да.... ОЧЕНЬ (вот просто люто-бешено) хочется чтобы всё было в разных модулях
Добавлено спустя 19 секунд:Когда уже в FPC будет поддержка пространств имён
Re: Отношения многие ко многим
Добавлено:
28.06.2012 13:00:25
alexs
А кто мешает разнести по разным модулям?
Странная здача - из разряда сферических коней в вакуме...
Re: Отношения многие ко многим
Добавлено:
28.06.2012 13:30:24
Brainenjii
Модуль длиннее 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.
Как я это разнесу по разным модулям? Я знаю только костыльное полурешение с инклюдами...
Re: Отношения многие ко многим
Добавлено:
28.06.2012 14:06:38
zub
Такое в паскале наврятли появится, это скорее ошибка проектирования программы, чем недостаток языка.
Я обычно выкручиваюсь так
- Код: Выделить всё
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.
Правда классы плодятся как грибы, тоже не гут((
Re: Отношения многие ко многим
Добавлено:
28.06.2012 14:24:05
Brainenjii
хм... спасибо ^_^
это скорее ошибка проектирования программы
Вот часто слышу такое. Но не могу понять, что ошибочного в этой идее.
Есть класс, он должен иметь список учеников. Есть ученик, которому было бы очень неплохо знать, в каком классе он учится.
Почему для такой банальной ситуации приходится изворачиваться, заносить оба (дальше - больше) класса в один исходный файл или создавать абстрактный класс... Ну неудобно же
Re: Отношения многие ко многим
Добавлено:
28.06.2012 14:53:28
zub
Всё не может знать о всём. Голова ученика знает где учится, ногам это знать не обязательно, они ходят туда куда скажет голова))
ИМХО всё бить на "атомарные" состовляющие и из них уже составлять нужные структуры - вполне логичный подход
Re: Отношения многие ко многим
Добавлено:
28.06.2012 14:56:19
Brainenjii
но почему-то в том же 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.
Почему-то порочной считается именно сама циклическая связь между классами... Но ведь, блин, она очевидна и правильна >_<
Re: Отношения многие ко многим
Добавлено:
28.06.2012 15:25:21
zub
>>Но ведь, блин, она очевидна и правильна >_<
а в каком порядке юниты инициализировать? Цикличные ссылки даже если их вынести за 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.
Re: Отношения многие ко многим
Добавлено:
28.06.2012 15:43:30
Brainenjii
в идеале хотелось бы, чтобы модули, установленные в одном 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 обретёт смысл и вообще... Классно же было бы, и удобно...
Re: Отношения многие ко многим
Добавлено:
28.06.2012 16:04:32
stikriz
Все дело в том, что ученик - это один объект, класс - это другой, а расписание или история, где он учился - это третий. Вот тогда все встает на свои места. Если бы это было в БД, то третья нормальная форма обязала бы нас сделать еще одну таблицу с двумя форейгнкеями на учеников и на классы.
Re: Отношения многие ко многим
Добавлено:
28.06.2012 16:15:57
Brainenjii
история это конечно круто... Но проблему, толком, не решает... А дополненная реализация namespace'ов - решила бы...
Я понимаю, если бы этого нигде не было и всегда говорили бы "фи"... Но, блин, в современных языках такое реализуется довольно просто и выгода очевидена и велика... А уж как тесты бы славно легли на такой механизм....
Re: Отношения многие ко многим
Добавлено:
28.06.2012 16:18:55
stikriz
Это только вначале паскаль кажется ущербным. Потом понимаешь, что так оно наиболее логично. Кстати, паттерны поизучайте - меньше будет таких извратов.
Re: Отношения многие ко многим
Добавлено:
28.06.2012 16:27:10
Brainenjii
Ещё раз.
Есть класс, он должен иметь список учеников. Есть ученик, которому было бы очень неплохо знать, в каком классе он учится.
Что извращённого в желании реализовать такое? Какой анти-паттерн существует для такой структуры?
З.Ы. и 3 нормальная форма не имеет никакого отношения к озвученной проблеме