Re: Дерево полиморфных объектов (ООП)
От: Trean Беларусь http://axamit.com/
Дата: 12.10.05 15:16
Оценка: 2 (1)
Здравствуйте, der_user, Вы писали:

_>На самом деле, это "древовидный граф" (у него один корень, и он иерархичен, ... всё бы ничего, однако некоторые его узлы могут иметь по несколько родителей).

_>Проблема в том, что он на самом деле должен содержать полиморфные объекты; объекты-узлы разных типов могут иметь потомков и родителей разных типов (множество комбинаций для каждого типа определено), причем:

_>1. Необходимо обеспечить безопасное удаление элементов, чтобы при удалении объекта все его "соседи" об этом знали.


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

_>2. Допустим, есть объект a класса A, его потомками могут быть объекты классов B и C. Нужно обеспечить возможность получения клиентом от объекта a двух множеств: "потомки a, класса B" и "потомки a, класса C".


Создать опять же класс внешний, который будет хранить ссылку на граф или получать ее как параметр вызова метода, передать сам объект в метод, и некий идентификатор класса-фильтра (это уже зависит от языка программирования). У графа получаете коллекцию соседей, которую фильтруете по типу, и возвращаете уже отфильтрованную.

_>3. Не повредило бы наличие средства для локальной работы с "поддеревьями".


Что может быть проще, концепция субграфа. Я наследовал субграф от графа, таким образом получая все его методы, и добавлял несколько своих, разумеется методы добавления/удаления вершин и некоторые другие пришлось переопределить. Причем субграф не делал копии объектов, а имел только ссылки на уже существующие в "суперграфе", это существенно уменьшает объем используемой памяти.

_>4. А если это всё, да ещё и попотокобезопаснее, -- это было бы более, чем замечательно.


Pattern Decorator он же Wrapper, для каждого метода делаете синхронизированную обертку.

_>5. Пробовал заключить информацию о родителях/потомках в сами классы -- ничего хорошего. Теперь собираюсь сделать "менеджера связей", в этой связи напрашивается использование БД, но, насколько я знаю, с рекурсивными алгоритмами (а их у меня множество) запросы БД лучше не мешать (или мешать, но как -- мне не известно), и, наконец, как же быть с пунктом 3 ?


"Менеджер связей" еще называется инцидентором, есть несколько вариантов представлений графов, но с инцидентором самый правильный
Я бы не стал такую логику пихать в базу данных, но в Oracle и SapDB есть специальные функции для обхода дерева представленного таблицей, можете попробовать.

_>6. Работать, видимо, придется, ограничивая доступ к узлам дерева прокси-интерфейсом в сочетании с фабриками (удаление, создание объектов). Прав ли я ?


Насчет фабрики, лучше создание объектов разрешить исключительно самому дереву или графу, это правильно уже с логической точки зрения: ребро и вершина, не рассматриваются в теории графов отдельно вне контекста какого-то графа. Лучше всего установить графу необходимые фабрики, а затем вызывать метод типа createNone (если типов вершин несколько — придется передавать и тип).

_>7. И ещё один тупой вопрос: как в данном случае лучше организовывать доступ объектов-узлов к менеджеру: хранить в объекте ссылку на менеджера, полученную при создании объекта, или юзать оного глобально ?


Объекты узлы ИМХО не должны знать от контейнере или менеджере, а еще лучше чтобы и контейнер не знал типов объектов и их внутреннего устройства. Этого всегда можно избежать. Вообще, я на архитектуру подобной библиотеки потратил месяца 2, зато на данный момент меня все устраивает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.