Я создаю веб-приложение PHP, которое должно предоставить пользователю возможность заказать «установку» / настройку соединения (ConnectDirect или File Transfer Gateway) между ним и другим человеком / организацией.
(Техническая спецификация реализации соединения не важна – в приложении речь идет только о соединениях как продуктах, которые можно заказать и управлять).
Иерархия классов для своего модельного слоя должна представлять собой следующую инфраструктуру реального мира:
Поэтому я вижу следующие логические элементы: логическое соединение , физическое соединение , роль ( источник и цель ), тип подключения , порядок , конечная точка, тип конечной точки (CD и FTGW).
Структура, которую я сейчас выгляжу, выглядит следующим образом:
Но есть некоторые проблемы:
Существует два дерева иерархии , каждый из которых состоит из элементов определенного подмножества другого (каждое соединение с CD состоит из конечных точек CD, каждое соединение FTGW состоит из двух конечных точек FTGW или, что более правильно: каждое логическое соединение FTGW состоит из два физических соединения FTGW – и каждая из них состоит из конечной точки FTGW и сервера FTGW в качестве второй конечной точки).
Альтернативой может быть замена отношений между конечной точкой и PsysicalConnection
двумя отношениями: EndpointCD-PsysicalConnectionCD
и EndpointFTGW-PsysicalConnectionFTGW
.
Pro : более последовательный; исключает логическую неточность (или, может быть, даже ошибку ) фальшивой возможности построить каждое соединение (тип) из пары любых конечных точек. Contra : На самом деле требование содержать две конечные точки является характеристикой каждого физиологического соединения – с этой точки зрения правильным местом для этого является самый простой класс PsysicalConnection
.
Каждая конечная точка может быть как исходной, так и целевой и содержит не только общие свойства конечной точки, но и исходные и целевые свойства . Это означает, что в зависимости от роли конечной точки некоторые свойства являются отходами . И это также будет влиять на структуру базы данных (столбцы, которые иногда должны быть установлены, а иногда и должны иметь бит NULL
).
Альтернативой является расширение иерархии …
а. … такими классами, как EndpointSource
и EndpoitTarget
наследующими непосредственно от EndpoitTarget
Endpoint
и наследуемыми классами EndpointCD
и EndpointFTGW
(что означает: два идентичных поддеревья – в EndpointSource
и под EndpointTarget
);
б. … такими классами, как EndpointCDSource
и EndpointCDTarget
(наследующий от класса EndpointCD
) и EndpointFTGWSource
и EndpointFTGWTarget
(наследующий от класса EndpointFTGW
), унаследованный каждым из конкретных классов конечных точек CD или FTGW (что означает: дважды два одинаковых поддерева);
с. … по классам, таким как MyConcreteEndpoint***Source
и MyConcreteEndpoint***Target
наследование от конкретных классов конечных точек (это означает, что каждый класс MyConcreteEndpoint
становится абстрактным и получает две MyConcreteEndpoint***Source
– MyConcreteEndpoint***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.. } ] }