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

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

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

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

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

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

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

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

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

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

    Альтернативой может стать замена отношений между Endpoint а также PsysicalConnection двумя отношениями: EndpointCD-PsysicalConnectionCD а также EndpointFTGW-PsysicalConnectionFTGW,

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

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

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

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

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

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

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

    профессионал: устраняет свойства отходов. против: (Более) сложная иерархия классов.

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

16

Решение

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

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

Так:

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

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

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

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

Вот:

  • LogicalConnection — это ссылка на встроенную композицию реальных классов Connection, Node и Protocol.

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

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

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

  • Целевые и исходные узлы «видят» друг друга и конфигурацию исходного-целевого протокола через двойную структуру списка.

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

  • Пространства имен IBM \ ConnectDirect \ и IBM \ FTGW \ содержат конкретные реализации для протокола и * узла (например, 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..
}
]
}
1

Другие решения

Других решений пока нет …