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

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

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

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

Сообщение stikriz » 28.06.2012 16:34:21

Brainenjii писал(а):Что извращённого в желании реализовать такое? Какой анти-паттерн существует для такой структуры?

Есть список классов, есть список учеников, а есть соответствие между классами и учениками.
Например, как Вы переведете ученика в другой класс? Вам надо в трех объектах поменять данные: убрать из одного класса, вставить в другой класс, поменять в третьем классе. Имея нечто вроде соответствия, вы делаете одну операцию: находите ученика, и меняете ему класс. Дальше продолжать? А то, я могу еще про создание и удаление объектов и кто это должен делать :-) А вообще, есть же другие современные языки, так ведь, которые любой изврат помогают сделать :-) Там, наверное, лучше?

Добавлено спустя 1 минуту:
Brainenjii писал(а):3 нормальная форма не имеет никакого отношения к озвученной проблеме

Имеет.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

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

Сообщение Brainenjii » 28.06.2012 16:50:20

Это всё, конечно, хорошо и понятно. Если мне, вдруг, захочется держать такую информацию - что мне мешает сделать соответствующий Getter, который будет к той самой истории обращаться? Ссылка у ученика на его текущий класс - это банальный кеш. Со всеми Вами описанными проблемами по его обновлению. Просто я хочу, чтобы этот кеш был под рукой, а именно - членом класса! Проблема в том, что мой любимый паскаль (я не тролль, честно) мне этого сделать не даёт! Ну мне не влом пробежаться по классам и сделать там соответствующие перестановки поскольку мне это нужно делать раз в 1000 реже, чем находить - какой ученик какому классу принадлежит и наоборот. Тем паче что ВСЕ необходимые ссылки у меня всегда будут под рукой! Мне не нужно перелопачивать список учеников в поисках нужного! Если вдруг возникнет желание рассказать мне про ускорение поиска, бинарные деревья, hash-таблицы - не стоит. Я всего лишь хочу иметь возможность реализовать то же что мне паскаль ПОЗВОЛЯЕТ сделать конструкцией
Код: Выделить всё
Type ClassA = Class;
Type ClassB = Class
  Public
    Property A: ClassA Read fA;
end;

Type ClassA = Class
  Public
    Property B: ClassB read fB;
End;

Но разбив это по разным модулям, потому что так удобнее, когда классы становятся больше 1000 строк кода.

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

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

Сообщение stikriz » 28.06.2012 17:04:36

Brainenjii писал(а): что ООП должно предоставлять немножко больше возможностей, нежели алгебра множеств, разве нет?

Нет. Стоит ограничится здравым смыслом, а дальше не лезть :-) Эта задача как раз из теории множест, и так её и надо решать.
Brainenjii писал(а):Ну мне не влом пробежаться по классам и сделать там соответствующие перестановки поскольку мне это нужно делать раз в 1000 реже, чем находить - какой ученик какому классу принадлежит и наоборот.

А Вы где будете хранить данные? Если в БД (а то где же еще?), то вместо изучения деревьев можно потренироваться с запросами на SQL. И архитектура БД все равно перенесется в код программы. А с соответствием можно разнести на три модуля :-)
Дело не в ломе. Дело в том, что дальше-больше. Начнуться проблемы, что ученик думает, что он в 5-а классе, а он в 9-б... А то хуже - сразу в нескольких или нигде. Один из паттернов гласит, что "если грабля может быть в принципе, то она будет обязательно рано или поздно".
Я не спорю, надеюсь, что на таком простом примере, как у Вас, кто-то да понял, почему паскаль создан для обучения, да потому, что он логичен. А там, хоть как пишите - это Ваша программа.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

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

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

Т.е. вариант с getter'ом и сентенцию про кеш вы проигнорировали ^_^ А при неграмотном проектировании и реализации - и таблица соответствий не спасет. При грамотном ситуация со сбоем кеша не произойдет. Хотя разумеется, сложность повышается на порядки. Или нужно вообще взять и дружно отказаться от кеширования, потому что оно опасно? :-D
Да и даже речь не о том вообще >_< Даже более простой случай - отношение один к одному - и то я не могу сейчас реализовать, разбив связанные классы по модулям >_< И более сложный, указанный, к слову, в названии темы. И не могу, не потому что это неправильно или некорректно (забудьте про кеш, пусть свойство Grade вернёт мне текущий класс из таблицы соответствий - к этому нет претензий?). А просто потому что нельзя.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение stikriz » 28.06.2012 17:33:03

Brainenjii писал(а):Т.е. вариант с getter'ом и сентенцию про кеш вы проигнорировали

Просто, откладывание смысла на абстракцию ничего не говорит о смысле сказанного :-) Какая разница к кому Вы обращаетесь, к проперти класса или к некому соответствию, типа менеджера? Сделайте у соответствия функцию , типа, дать список учеников и дать класс ученика. А как там внутри будет кэш сделан - это проблемы реализации. Мы же обсуждаем абстракции реального мира?
Brainenjii писал(а):Даже более простой случай - отношение один к одному - и то я не могу сейчас реализовать, разбив связанные классы по модулям

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

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

Сообщение Brainenjii » 28.06.2012 17:40:49

Разница довольно большая ^_^ В одном случае - я каждый раз когда хочу получить текущий класс ученика должен нарушать абстракцию и инкапсуляцию и всему свету трезвонить, что у меня есть какая-то таблица соответствий. Причем многословно, с обращением к объекту другого класса (не уходя, между прочим, от циклических ссылок). Хотя в реальной жизни ученику не нужна никакая таблица - он сам прекрасно всё знает...
чем мне это поможет, если я наоборот хочу уйти от необходимости сводить 2 класса в один модуль? Тут скорее вариант т-ща zub'a подойдёт, но с необходимостью поддерживать ещё и абстрактный класс в актуальном состоянии. Да и вообще костыль. При том что система пространства имён, прекрасно себя зарекомендовавшая в java, довольно хорошо ложится к FPC и решает эту и ещё несколько проблем (где-то выше была тема про дружественные классы)
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение alexs » 28.06.2012 17:49:30

Brainenjii
В чём проблема?
Проведите декомпозицию до конца вашей ПО. У вас на самом деле есть для ученика родительская сущность, от который наследовать надо - человек.
Вот вынесите его в отдельный модуль. И всё будет в шоколаде.
Дальше вы захотите сделать преподователя. И будет всё уже подготовлено.
А на самом деле - возьмите нормальную БД и не мучайтесь.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение Brainenjii » 28.06.2012 18:43:54

>_< Так я могу провести декомпозицию ещё дальше и оставить ссылку на TList или TObject. Ибо от приведения типов мне это самая декомпозиция ничего не поможет. При чем здесь БД вообще непонятно... В общем, я понял что мне надо делать ^_^ Скоро стрельну очередным шедевром :-D
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение alexs » 28.06.2012 19:44:01

Brainenjii писал(а): оставить ссылку на TList или TObject.

Не надо подменять понятия.
Эти объекты - элементы реализации.
Я говорил про абстрактные классы.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение Brainenjii » 28.06.2012 20:07:51

Согласен, съёрничал ^_^ Но суть не изменится. Ученики в классе меня интересуют ИМЕННО как ученики. С оценками, родителями и всеми остальными сведениями об учениках. Оценки и родители учителей меня интересуют чуть менее чем никак. Создать класс, который будет точь-в-точь как ученик и затем наследовать ученика от него - это и будет решение т-ща zub'a, которое будет значительно многословней решения на связанных классах...
В общем, неужели я хочу так многого - разбить конструкцию
Код: Выделить всё
Type TPupil = Class;
Type TPupils = Specialize TFPGList<TPupil>;
Type TGrade = Class
  Private
    fPupils: TPupils;
    Function GetPupils: TPupils
  Public
    Property Pupils: TPupils Read GetPupils;
End;
Type TPupil = Class
  Private
    Function GetGrade: TGrade;
  Public
    Property Grade: TGrade Read GetGrade;
End;

Всё! Шикарно работающее решение, надёжно инкапсулирующее от пользователей классов TPupil/TGrade то что есть какая-то таблица соответствий. Которое перестаёт работать стоит мне разнести эти два класса по разным модулям. Да, блин, каждый второй модуль в самом Lazarus'е грешит конструкцией "Forward class declarations" <ClassName> = Class; которая, если верить фразе "скорее ошибка проектирования программы, чем недостаток языка." (из-за которой, если кто помнит, и начался весь флейм). Вот только если циклические ссылки идут в одном модуле - то всё хорошо и нормально, а если в нескольких - то сразу же оказывается, что проектировщик дурак и на самом деле есть изящные и правильные решения, не то что... Неужели вы в самом деле в это верите?
Решение товарища stikriz'a заставляет каждый раз когда мне нужен текущий класс, в котором учится ученик обращаться к третьему классу, что явным образом нарушает инкапсуляцию. Решение товарища alexs'a - заставляет либо пользоваться приведением типа, либо реализовывать костыльный механизм подстановки ненужного мне класса, некоторым образом напоминающее решение товарища zub'a.
А если попробовать перестать упираться в "ненужности" возможностей namespace'ов - все ведь решится и решится довольно изящно. Равно как ещё довольно внушительный набор проблем.
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение alexs » 28.06.2012 20:31:24

Brainenjii
Вы сами себе противоречите.
Не хотите сторить данные правильно. Но боритесь с костылями, которые сами себе и придумали.
1. Если хотите постороить абстрактную систему для эксперемента - то надо идти с декомпозицей до нужного минимума. А вы свою предметную область чуть по вершкам дёрнули и остановились.
2. Если строить реальную систему - то вам уже не раз указали, что надо брать правильный иснтрумент для хранения данных (СУБД) а не заниматься не нужными построениями неизвестно чего.
И в первом и во втором случае - надо сначала грамотно спроектировать систему (данные). А потом писать код.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение Brainenjii » 28.06.2012 21:16:58

Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение B4rr4cuda » 28.06.2012 21:17:19

Честно скажу - весь топик не читал, глубоко не разбирался, но имхо может посмотреть в сторону интерфейсов?
Аватара пользователя
B4rr4cuda
энтузиаст
 
Сообщения: 693
Зарегистрирован: 28.12.2007 07:48:35

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

Сообщение Brainenjii » 28.06.2012 21:32:54

Да тут нечего читать ^_^ Топик-стартер спросил - нет ли какого красивого решения для создания перекрёстных ссылок между классами, расположенных в разных модулях. Решение, правда костыльное - напоминающее Proxy, но для другой задачи, было найдено. Потом пошло полторы страницы флейма, где автор пытался указать, что возможности, предоставляемые в рамках одного модуля, отбирать при разнесении на несколько модулей - нехорошо и неправильно, предлагал, как ему, наивному, казалось, неплохое решение, на что его наставляли на путь истинный с переработкой архитектуры, нарушениями инкапсуляции, сомнительной нужности обработчиками и/или все теми же костыльными классами ^_^
Интерфейсы - это тоже хорошо, но блин, не для этой задачи ^_^ Интерфейсы требуются для обработки нескольких несвязанных классов одним кодом (косноязычу уже под вечер), а тут, блин, перекрестные ссылки между классами ^_^ Да, можно и интерфейсами решить эту задачу, но это все-равно будет не самый удобный для данной задачи костыль.
При том, что не только я столкнулся с этой проблемой. И более того, она прекрасно разрешена уже во многих языках. Но, блин, наш человек все-равно будет писать модули по 5-10 тысяч строк, закидывая в них всё что должно быть в одном пространстве, изобретая безумные костыли, чтобы достучаться до приватных методов для модульного тестирования и думать не захочет, что где-то что-то может быть хоть как-то по-другому.
Можно же пересмотреть архитектуру и запихнуть в один модуль! Хей-хо!
Грустно всё...
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

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

Сообщение zub » 28.06.2012 22:55:13

Тов. Brainenjii нету в паскале пространства имен, в нем есть модульность. И то что вам неудобно читать портянки больше 700 строк не повод городить из паскаля ++ или не в суе упомянут #. Что толку от юнита если для он тянет за собой еще десяток аналогичных (а не ниже в иерархии) - формально это тоже самое что пихнуть всё в один юнит
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Пред.След.

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

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

Сейчас этот форум просматривают: Google [Bot] и гости: 15

Рейтинг@Mail.ru
cron