Tengo algunos problemas para encontrar una solución adecuada para el siguiente problema de arquitectura.
En nuestro entorno (esbozado a continuación) tenemos 2 fuentes de datos, donde la fuente de datos A es la fuente principal para los elementos de tipo Foo. Existe una fuente de datos secundaria que se puede utilizar para recuperar información adicional sobre un Foo; Sin embargo, esta información no siempre existe.
Además, la fuente de datos A se puede utilizar para recuperar elementos de tipo Bar. Sin embargo, cada barra se refiere a un Foo. La dificultad aquí es que cada barra debe referirse a un Foo que, si está disponible, también contiene la información aumentada por la fuente de datos B.
Mi pregunta es: ¿cómo eliminar el acoplamiento estrecho entre SubsystemA.1 y DataSourceB?
fuente
DataSourceA
yDataSourceB
ya están desacoplados?DataSourceA
tiene una dependencia en tantoSubSystemA.1
ySubSystemA.2
, pero no enDataSourceB
.SubsystemA.1
para usar algo diferenteDataSourceB
,DataSourceA
no lo sabría.DataSourceA
solo le importa queSubsystemA.1
tenga ungetFoo(id)
método. Hay una abstracción entreDataSourceA
yDataSourceB
.Respuestas:
Creé una aplicación con la misma arquitectura de datos detrás de ella; tenemos una base de datos SQL in situ que contiene la mayor parte de la automatización y la información interna diaria, y luego un servicio en la nube de terceros utilizado para ventas, administración de cuentas, personal de campo, etc. El servicio de asistencia necesitaba información de ambos con respecto a las ubicaciones físicas de los clientes y equipo, y lo había estado obteniendo de dos aplicaciones diferentes hasta que entré.
En resumen, una fuente de datos debe tener una referencia a los registros de la otra. En nuestro caso, los datos de la nube de terceros contienen referencias a los datos en el sitio porque ese es el acuerdo sobre el que teníamos más control. Ahora, con una ID para un registro de cualquier fuente de datos, podemos obtener datos de ambos; con una ID de nube, extraemos el registro de la nube, obtenemos la ID en el sitio y extraemos los datos en el sitio. Con una identificación en el sitio, encuestamos ambas fuentes de datos en función de esa identificación.
En mi sistema, no hice que ninguno de los objetos fuera hijo del otro en la capa de dominio; Cualquier uso de los datos de ambas tiendas debe mantener dos instancias de objeto. No se garantiza que ninguno exista, por eso lo hice así; la aplicación puede funcionar solo con datos en la nube, o con datos en el sitio, o ambos, con más limitaciones cuanto menos datos tenga.
Sin embargo, eso no es difícil de cambiar, especialmente si está seguro de que siempre existirá un lado; simplemente incluya una propiedad en el objeto que represente el lado para el que siempre existirán datos, que es del tipo de objeto que representa el registro del otro almacén de datos. Es posible una "fusión" más avanzada de los dos gráficos en uno.
Este tipo de arreglo necesariamente debe estar acoplado en algún nivel. Puede tener un DAL que pueda interactuar con ambos almacenes de datos, o puede segmentar los DAL, uno por almacén de datos, y hacer que una capa superior, como un Controlador, obtenga los datos de cada uno y los junte. Pero, en algún nivel, su programa tiene que tener la inteligencia para juntar estas dos fuentes de datos dispares.
Puede reducir el acoplamiento requerido en la mayoría de los casos abstrayendo detalles de dónde provienen los datos exactamente. Si obtiene datos de un servicio web, que se le proporciona como instancias de clases generadas, coloque un convertidor para hacer una copia profunda de la clase de servicio en algo que controle, que no tendrá que cambiar si los datos la fuente lo hace (solo si el esquema lo hace).
Ahora, esto puede ser una gran empresa; la nube que utilizamos tiene docenas de clases de dominio, algunas de las cuales tienen cientos de campos de datos y, aquí está el truco, es muy fácil que tengas que hacer grandes cambios en el tipo de datos abstractos para acomodar un movimiento a una nube diferente u otro control remoto fuente de datos. Por esa razón, no me molesté; Utilizo el dominio del servicio web generado directamente, y ahora que se avecina un cambio de la nube a un almacén de datos externo (pero bajo nuestro control), cuyos detalles aún no sé, simplemente estoy planeando cambiar los formularios y código detrás de la aplicación, que es donde los datos se "combinan", para reflejar el nuevo esquema y / u objetos de datos. Es un gran trabajo de cualquier forma que lo corte.
fuente
Una forma de lidiar con esto es hacer una fuente de datos agregada que contenga los datos de ambas fuentes de datos en un solo lugar. Un trabajo sería ejecutar periódicamente para comprobar si hay cambios en las fuentes
A
yB
, y escribir los "deltas" en el origen de datos agregada. Esto convertiría dos fuentes de datos estrechamente acopladas en una única fuente de datos coherente.Varias cosas podrían evitar que tome este enfoque:
A
yB
duplicar los requisitos de espacio.fuente
DataSourceA
yDataSourceB
ya están desacoplados?DataSourceA
tiene una dependencia en tantoSubSystemA.1
ySubSystemA.2
, pero no enDataSourceB
.Parece que en el nivel superior hay dos tipos: Foo y Bar, y solo tienes dos acciones de nivel superior:
findFoo(...)
yfindBar(...)
. Esa es la interfaz con la capa de E / S.Su descripción de las fuentes de datos implica que hay dos métodos en A:
findFoo
yfindBar
y un método de B:findFooAuxiliaryInformation
. EnfindFoo
deberá fusionar la información de A y B.No estoy seguro de a qué "acoplamiento apretado" se refiere. Hay tres tipos de datos contenidos en los dos conjuntos de datos:
Bar
,Foo
, yFooAuxData
. El acoplamiento entreFoo
yFooAuxData
es inherente a los datos de entrada, y no se puede reducir. Pero ese acoplamiento debería aparecer solo en elfindFoo
método. Eso es lo mejor que puedes hacer. El requisito se implementa en un solo lugar. Si cambia, debe cambiar ese código.fuente
No puedes
Si entiendo correctamente,
Foo
yBar
vengo dedsA
.Bar
s pertenece aFoo
s.Preferiblemente, no desea
Bar
asignar s aFoo
s, a menos queFoo
haya sido complementado porFoo.enhancedInfo
esodsB
.Su preferencia por asignar
Bar
s aFoo
s es lo que está creando su acoplamiento estrecho. Calificaría eso como un "desafío de requisitos" que lo obliga a seguir un camino en particular.Por lo tanto, los desafíos técnicos son que
dsB
pueden o no tener información sobre cualquier cosaFoo
y quedsB
incluso pueden no estar disponibles.Debe decidir qué tan dura y rápida
Foo.enhancedInfo
es realmente esa preferencia . Según ese requisito, puede decidir proporcionar un objetoFoo
+Bar
o no. PermitirFoo
que se proporcione un no mejorado solo complica la lógica y me dice que la preferencia no es tan estricta como parece. Determine qué variantes deFoo
,Foo.enhanced
yBar
sus aplicaciones pueden admitir y tendrá su respuesta definitiva.Hay otras cosas que podría hacer para acercar la
Foo
información relacionada, y eso podría resolver algunos de estos problemas. Por la forma en que se formula su pregunta, parece que está lidiando con el problema a nivel de objeto de datos y es posible que no pueda considerar los cambios de tipo de infraestructura.fuente
Si los datos en la fuente de datos B no pueden sostenerse por sí mismos, es probable que desee migrarlos a la fuente de datos A si es posible.
Si son independientes pero están relacionados, debe considerar la virtualización de datos . Esto permitirá que las aplicaciones traten los datos como un conjunto (cuando sea apropiado) de manera agnóstica. Dependiendo de su plataforma, probablemente habrá un marco / biblioteca existente que puede ayudarlo a implementar esto.
fuente