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

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

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

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

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

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

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

connections&endpoints pseudo UML class diagramm

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

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

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

replaced relationships

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

  1. Каждая конечная точка может быть и исходной и целевой, а содержит не только общие свойства конечной точки, но и источник и целевые свойства. Это означает, что в зависимости от роли конечной точки currnt некоторые свойства отходы. И это также будет влиять на структуру базы данных (столбцы, которые иногда должны быть установлены, а иногда и должны быть би 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: устраняет свойства отходов. Contra: более сложная иерархия классов.

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

Ответы

Ответ 1

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

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

Итак:

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

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

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

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

Здесь:

  • LogicalConnection - это ссылка на встроенную композицию фактического соединения, node и классов протокола

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

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

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

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

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

  • Пространства имен IBM\ConnectDirect\и IBM\FTGW\содержат конкретные реализации для протокола и * Node (например, WindowsNode, UnixNode)

Если по-прежнему существует потребность в node или в протоколе содержать как исходные, так и целевые атрибуты, а часть из них по-прежнему может быть 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..
    }
  ]
}