Как построить структуру класса, когда члены также структурированы иерархически?

Я создаю веб-приложение PHP, которое должно предоставить пользователю возможность заказать «установку» / настройку соединения (ConnectDirect или File Transfer Gateway) между ним и другим человеком / организацией.

(Техническая спецификация реализации соединения не важна – в приложении речь идет только о соединениях как продуктах, которые можно заказать и управлять).

Иерархия классов для своего модельного слоя должна представлять собой следующую инфраструктуру реального мира:

  • Есть соединения , которые можно заказать.
  • Соединение может быть соединением IBM Connect: Direct или соединением шлюза IBM File Transfer Gateway.
  • Соединение с CD напрямую от A ( источник ) до B ( цель ).
  • Соединение FTGW состоит из двух соединений: A (источник) на FTGW-сервере и от FTGW-сервера до B (target), но логически (для пользователя-заказчика) это также одно соединение.
  • (Кроме того, есть случай подключения FTGW, в котором используется Connect: Direct как protokoll.)
  • Каждая конечная точка является либо источником, либо целью.

Поэтому я вижу следующие логические элементы: логическое соединение , физическое соединение , роль ( источник и цель ), тип подключения , порядок , конечная точка, тип конечной точки (CD и FTGW).

Структура, которую я сейчас выгляжу, выглядит следующим образом:

соединений и конечных точек псевдо-диаграммы классов UML

Но есть некоторые проблемы:

  1. Существует два дерева иерархии , каждый из которых состоит из элементов определенного подмножества другого (каждое соединение с CD состоит из конечных точек CD, каждое соединение FTGW состоит из двух конечных точек FTGW или, что более правильно: каждое логическое соединение FTGW состоит из два физических соединения FTGW – и каждая из них состоит из конечной точки FTGW и сервера FTGW в качестве второй конечной точки).

    Альтернативой может быть замена отношений между конечной точкой и PsysicalConnection двумя отношениями: EndpointCD-PsysicalConnectionCD и EndpointFTGW-PsysicalConnectionFTGW .

заменили отношения

Pro : более последовательный; исключает логическую неточность (или, может быть, даже ошибку ) фальшивой возможности построить каждое соединение (тип) из пары любых конечных точек. Contra : На самом деле требование содержать две конечные точки является характеристикой каждого физиологического соединения – с этой точки зрения правильным местом для этого является самый простой класс PsysicalConnection .

  1. Каждая конечная точка может быть как исходной, так и целевой и содержит не только общие свойства конечной точки, но и исходные и целевые свойства . Это означает, что в зависимости от роли конечной точки некоторые свойства являются отходами . И это также будет влиять на структуру базы данных (столбцы, которые иногда должны быть установлены, а иногда и должны иметь бит NULL ).

    Альтернативой является расширение иерархии …

    а. … такими классами, как EndpointSource и EndpoitTarget наследующими непосредственно от EndpoitTarget Endpoint и наследуемыми классами EndpointCD и EndpointFTGW (что означает: два идентичных поддеревья – в EndpointSource и под EndpointTarget );

    б. … такими классами, как EndpointCDSource и EndpointCDTarget (наследующий от класса EndpointCD ) и EndpointFTGWSource и EndpointFTGWTarget (наследующий от класса EndpointFTGW ), унаследованный каждым из конкретных классов конечных точек CD или FTGW (что означает: дважды два одинаковых поддерева);

    с. … по классам, таким как MyConcreteEndpoint***Source и MyConcreteEndpoint***Target наследование от конкретных классов конечных точек (это означает, что каждый класс MyConcreteEndpoint становится абстрактным и получает две MyConcreteEndpoint***SourceMyConcreteEndpoint***Source и MyConcreteEndpoint***Target , например, EndpointCDLinux теперь абстрактно и наследуется EndpointCDLinuxSource и EndpointCDLinuxTarget ).

    Pro : устраняет свойства отходов. Contra : (более) сложная иерархия классов.

Ну, речь идет о архитектуре программного обеспечения и должно (и, конечно же, будет) быть моим дизайнерским решением. Но было бы неплохо услышать / прочитать некоторых экспертов (или неспециалистов), как справиться с таким делом. Каковы правильные способы организации логических элементов для инфраструктуры, как то, что я описал?

Возможно, я слишком задумываюсь, но я предлагаю вам использовать немного другую модель, чтобы отразить вашу бизнес-логику.

Следующее может быть полным недоразумением, но я сделаю это.

Так:

Основываясь на том, что на самом деле какая-либо связь, вот понятие:

  • Каждое соединение представляет собой совокупность узлов, через которые данные должны перемещаться, чтобы добраться до места назначения.
  • Каждый узел может подключаться к следующему узлу с использованием определенного протокола, который специфичен только для прямого соединения между двумя конкретными узлами.
  • Протокол имеет свои собственные свойства, общие для исходных и целевых узлов

Исходя из этого, я предлагаю следующую модель построения, управления и хранения конфигурации продукта:

введите описание изображения здесь

Вот:

  • LogicalConnection – ссылка на построенный состав фактических классов Connection, Node и Protocol

  • Соединение содержит двойной список узлов, которые составлены в порядке потоковой передачи данных. т.е.: 1-й элемент является исходным узлом, а второй – его целью и так далее.

  • Конкретный узел содержит конфигурацию на платформе, ссылку на целевую (* Node), исходный узел (* Node) и конкретный протокол (* Протокол)

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

  • Целевые и исходные узлы "см." Конфигурация каждого другого и источника-целевого протокола через структуру с двойными связями.

  • Конфигурации \ * Реализации ConfigBuilder организуют процесс принятия данных из пользовательского интерфейса и преобразуют его в фактический состав Connection, Node и Protocol в зависимости от случая.

  • В пространствах IBM \ ConnectDirect \ и IBM \ FTGW \ names перечислены конкретные реализации для протокола и * узла (например, WindowsNode, UnixNode)

Если по-прежнему требуется, чтобы узел или протокол содержали атрибуты, связанные с источником и объектом, и часть из них все еще могла быть NULL в некоторых конфигурациях – я предлагаю использовать модель хранения EAV для БД, если есть какая-либо проблема с неиспользуемыми столбцами и т. Д.

Использование предложенных подключений модели, о которых вы описали, может быть представлено следующим образом:

 Connection:IBM_CD { nodes:[ {//LinuxNode target:*nextElement, protocol:{//IBM.ConnectDirect.Protocol ..target attributes.. ..source attributes.. } ..platform specific attributes.. }, {//WindowsShareNode target:*nil, protocol:{ //IBM.ConnectDirect.Protocol(same instance or null) } ..platform specific attributes.. }, ] } Connection:IBM_FTGW { nodes:[ {//LinuxNode target:*nextElement, source:*nil, protocol:{//IBM.FTGW.Protocol ..target attributes.. ..source attributes.. } ..platform specific attributes.. }, {//IntermediateServerLinuxNode target:*nextElement, source:*prevElement, protocol:{//IBM.FTGW.Protocol ..target attributes.. ..source attributes.. }, ..platform specific attributes }, {//WindowsShareNode target:*nil, source:*prevElement, protocol:*nil, ..platform specific attributes.. } ] }