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

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

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

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

  • Есть соединения, которые можно заказать.
  • Соединение может быть соединением IBM Connect:Direct или соединением IBM File Transfer Gateway.
  • Подключение CD напрямую от A (источник) к 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,

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

Pro: более последовательный; устраняет логическую неточность (или, возможно, даже ошибку) ложной возможности построить каждое соединение (тип) из пары любых конечных точек. Против: На самом деле требование содержать две конечные точки является характеристикой каждой физической связи - с этой точки зрения правильное место для этого является самым основным 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).

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

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

1 ответ

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

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

Так:

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

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

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

Вот:

  • 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..
    }
  ]
} 
Другие вопросы по тегам