Я создаю веб-приложение на PHP, которое должно предоставить пользователю возможность заказать «установку» / настройку (ConnectDirect или File Transfer Gateway) соединения между ним и другим человеком / организацией.
(Технические особенности реализации соединений не важны — в приложении речь идет только о соединениях как о продукте, которые можно заказать и управлять.)
Иерархия классов для ее уровня модели должна представлять следующую реальную инфраструктуру:
Итак, я вижу следующие логические элементы: логическая связь, физическая связь, роль (источник а также цель), тип соединения, порядок, конечная точка, тип конечной точки (CD и FTGW).
Структура, которую я сейчас имею, выглядит так:
Но есть некоторые проблемы с этим:
Есть два дерева иерархии, где каждый элемент одного состоит содержит элементы определенного подмножество другого (каждое соединение CD состоит из конечных точек CD; каждое соединение FTGW состоит из двух конечных точек FTGW, или, что более правильно: каждое логическое соединение FTGW состоит из двух физических соединений FTGW — и каждое из них состоит из конечной точки FTGW и сервера FTGW как вторая конечная точка).
Альтернативой может стать замена отношений между Endpoint
а также PsysicalConnection
двумя отношениями: EndpointCD-PsysicalConnectionCD
а также EndpointFTGW-PsysicalConnectionFTGW
,
профессионал: Более последовательный; устраняет логическую неточность (или, может быть, даже ошибка) фиктивной возможности построить каждое соединение (тип) из пары любых конечных точек. противНа самом деле требование содержать две конечные точки является характеристикой каждой физической связи — с этой точки зрения правильное место для этого PsysicalConnection
учебный класс.
каждый конечная точка может быть и то и другое источник и цель и содержит не только общие свойства конечной точки, но и исходные и целевые свойства. Это означает, что в зависимости от текущей роли конечной точки некоторые свойства отходы. И это также будет влиять на структуру базы данных (столбцы, которые иногда должны быть установлены и иногда должен би 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
).
профессионал: устраняет свойства отходов. против: (Более) сложная иерархия классов.
Ну, речь идет об архитектуре программного обеспечения и должна (и, конечно, будет) моим дизайнерским решением. Но было бы неплохо услышать / прочитать некоторые экспертные (или неэкспертные) мысли о том, как справиться с таким случаем. Как правильно организовать логические элементы для инфраструктуры, как я описал?
Может быть, я слишком много думаю, но я предлагаю вам использовать немного другую модель, чтобы отразить вашу бизнес-логику.
Следующее может быть полным недоразумением, но я попробую.
Так:
Основываясь на том, что на самом деле является любой связью, вот концепция:
Исходя из этого, я предлагаю следующую модель построения, управления и хранения конфигурации продукта:
Вот:
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..
}
]
}
Других решений пока нет …