php inheritance architecture software-design class-structure

php - ¿Cómo construir una estructura de clase, cuando los miembros también están estructurados jerárquicamente?



inheritance architecture (1)

Estoy creando una aplicación web PHP, que debería proporcionar al usuario la posibilidad de solicitar una "instalación" / configuración de una conexión (ConnectDirect o File Transfer Gateway) entre él y otra persona / organización.

(Las especificaciones técnicas de la implementación de la conexión no son importantes; en la aplicación solo se trata de las conexiones como producto, que se pueden solicitar y administrar).

La jerarquía de clases para su capa de modelo debe representar la siguiente infraestructura del mundo real:

  • Hay conexiones , que pueden ser ordenadas.
  • Una conexión puede ser una conexión de IBM Connect: Direct o una conexión de IBM File Transfer Gateway.
  • Una conexión de CD es directa desde A ( origen ) a B ( destino ).
  • Una conexión FTGW consta físicamente de dos conexiones: A (origen) al servidor FTGW y del servidor FTGW a B (destino), pero lógicamente (para el usuario que realiza el pedido) también es una conexión.
  • (También hay un caso de una conexión FTGW, que usa Connect: Direct como protokoll).
  • Cada punto final es una fuente o un objetivo.

Entonces veo los siguientes elementos lógicos: conexión lógica , conexión física , función ( origen y destino ), tipo de conexión , orden , punto final , tipo de punto final (CD y FTGW).

La estructura que tengo actualmente se ve así:

Pero hay algunos problemas con esto:

  1. Hay dos árboles de jerarquía , donde cada elemento del uno consiste en elementos de un subconjunto particular del otro (cada conexión de CD consiste en puntos finales de CD; cada conexión FTGW consta de dos puntos finales FTGW, o más correctamente: cada conexión lógica FTGW consiste dos conexiones físicas FTGW, y cada una de ellas consta de un punto final FTGW y el servidor FTGW como segundo punto final).

    Una alternativa podría ser reemplazar la relación entre Endpoint y PsysicalConnection por dos relaciones: EndpointCD-PsysicalConnectionCD y EndpointFTGW-PsysicalConnectionFTGW .

Pro : Más consistente; elimina la imprecisión lógica (o tal vez incluso el error ) de la posibilidad falsa de construir cada conexión (tipo) a partir de un par de puntos finales. Contra : En realidad, el requisito de contener dos puntos finales es una característica de cada conexión psíquica: desde este punto de vista, el lugar correcto para esto es la clase muy básica de PsysicalConnection .

  1. Cada punto final puede ser tanto de origen como de destino y contiene no solo las propiedades comunes de punto final, sino también las propiedades de origen y destino . Eso significa que, dependiendo de la función actual del punto final, algunas propiedades son residuos . Y esto también influirá en la estructura de la base de datos (columnas, que a veces deben establecerse y otras veces tienen que ser NULL ).

    Una alternativa es extender la jerarquía ...

    a. ... por clases como EndpointSource y EndpoitTarget heredan directamente de Endpoint y que las clases EndpointCD y EndpointFTGW heredan (esto significa: dos subárboles idénticos, en EndpointSource y en EndpointTarget );

    segundo. ... por clases como EndpointCDSource y EndpointCDTarget (heredado de la clase EndpointCD ) y EndpointFTGWSource y EndpointFTGWTarget (heredado de la clase EndpointFTGW ) que son heredadas cada una por el CD concreto o las clases de punto final de FTGW (es decir, dos clases de punto final idénticas);

    do. ... por clases como MyConcreteEndpoint***Source y MyConcreteEndpoint***Target heredado de las clases de endpoint concretas (es decir, cada clase MyConcreteEndpoint vuelve abstracta y obtiene dos subalidades - MyConcreteEndpoint***Source y MyConcreteEndpoint***Target , por ejemplo, EndpointCDLinux ahora es abstracto y es heredado por EndpointCDLinuxSource y EndpointCDLinuxTarget ).

    Pro : elimina las propiedades de los residuos. Contra : una (más) compleja jerarquía de clases.

Bueno, se trata de la arquitectura del software y debería (y por supuesto) será mi decisión de diseño. Pero sería bueno escuchar / leer algunos expertos (o no expertos), cómo manejar este caso. ¿Cuáles son las formas adecuadas de organizar los elementos lógicos para una infraestructura como la que describí?


Tal vez estoy pensando demasiado, pero le sugiero que use un modelo ligeramente diferente para reflejar la lógica de su negocio.

Seguir podría ser un malentendido total, pero lo intentaré.

Asi que:

Basándose en lo que de hecho es cualquier conexión, aquí hay un concepto:

  • Cada conexión es una colección de Nodos a través de los cuales los datos deben viajar para llegar a su destino.
  • Cada nodo puede conectarse con el siguiente nodo utilizando un protocolo específico, que es específico solo para la conexión directa entre dos nodos particulares.
  • El protocolo tiene sus propias propiedades comunes para los nodos de origen y destino.

Basándome en esto, sugiero seguir el modelo de construcción, administración y almacenamiento de una configuración de Producto:

Aquí:

  • LogicalConnection es una referencia a la composición construida de las clases reales de conexión, nodo y protocolo

  • La conexión contiene una lista de nodos con enlaces dobles que se componen en orden como flujos de datos. es decir: el primer elemento es el nodo de origen y el segundo es su objetivo y así sucesivamente.

  • El nodo concreto contiene la configuración específica de la plataforma, la referencia al objetivo (* nodo), el nodo de origen (* nodo) y el protocolo concreto (* protocolo)

  • El protocolo contiene su configuración específica para el origen y el destino, las instancias de nodo pueden hacer referencia a la instancia del protocolo para extraer la configuración requerida.

  • Los nodos de destino y de origen "ven" la configuración de los protocolos de origen y destino a través de una estructura de lista de enlaces dobles.

  • Configuraciones / * Las implementaciones de ConfigBuilder organizan el proceso de aceptar datos de la interfaz de usuario y transformarlos en la composición real de la conexión, el nodo y el protocolo, según el caso.

  • IBM / ConnectDirect / y IBM / FTGW / namespaces contienen realizaciones concretas para Protocolo y * Nodo (por ejemplo, WindowsNode, UnixNode)

Si todavía es necesario que Node o Protocol contengan atributos relacionados tanto con el origen como con el destino y parte de ellos aún podría ser NULL en algunas configuraciones. Sugiero usar el modelo de almacenamiento EAV para DB si existe alguna inquietud acerca de las columnas no utilizadas, etc.

El uso de las conexiones de modelo sugeridas que describió en la pregunta podría representarse de la siguiente manera:

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.. } ] }