Cómo reducir el acoplamiento estrecho entre dos fuentes de datos

10

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?

http://i.stack.imgur.com/Xi4aA.png

fstuijt
fuente
10
Ese es un hermoso boceto. ¿Qué programa usaste para dibujarlo?
Marcelo MD
También quiero saber qué programa usaste para dibujarlo. Por favor.
Tulains Córdova
2
yuml.me es el sitio que usó más que probable para crear el diagrama.
Jason Turner el
1
¿No están DataSourceAy DataSourceBya están desacoplados? DataSourceAtiene una dependencia en tanto SubSystemA.1y SubSystemA.2, pero no en DataSourceB.
Tulains Córdova
1
@fstuijt No, no lo es. Si modificas SubsystemA.1para usar algo diferente DataSourceB, DataSourceAno lo sabría. DataSourceAsolo le importa que SubsystemA.1tenga un getFoo(id)método. Hay una abstracción entre DataSourceAy DataSourceB.
Tulains Córdova

Respuestas:

3

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.

KeithS
fuente
Esta respuesta cubre mejor el problema que he encontrado y, en mi opinión, también ofrece la mejor respuesta hasta ahora. Sin embargo, creo que combinar datos de múltiples fuentes es un problema común. ¿Algún patrón de diseño que pueda ayudar?
fstuijt
1
Alguna variación en un patrón de Fábrica podría ser útil. Si tiene una CloudInvoice y un objeto SqlInvoice (de sus respectivas fuentes de datos) y desea crear una sola Factura unificada, cree una Fábrica que sepa lo suficiente sobre ambas fuentes de datos para recuperar cada mitad del registro que está por crear, y luego combina la información en su clase de dominio.
KeithS
4

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 Ay B, 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:

  • La cantidad de datos puede ser prohibitiva : es necesario realizar una copia completa Ay Bduplicar los requisitos de espacio.
  • Los datos deben estar activos : habrá períodos entre el momento en que los datos en la fuente han cambiado y el trabajo de agregación los ha propagado a la fuente agregada.
  • Debe conciliar los datos con las fuentes originales : la tarea de mover los cambios nuevamente a sus lugares originales se vuelve mucho más compleja si adopta este enfoque.
dasblinkenlight
fuente
Estoy de acuerdo, la introducción de una capa de abstracción es el enfoque preferido
neontapir
2
Puede tener una capa de abstracción sin copiar los datos.
smp7d
@ smp7d Esto ocultaría el acoplamiento detrás de un bonito frontal; Sin embargo, supuse que ya estaba haciendo algo así en su sistema, porque de lo contrario la complejidad se extendería en todo su diseño.
dasblinkenlight
Dependiendo del entorno de la base de datos, esto también podría manejarse con una o más Vistas, eliminando la necesidad de copiar datos.
Walter
¿No están DataSourceAy DataSourceBya están desacoplados? DataSourceAtiene una dependencia en tanto SubSystemA.1y SubSystemA.2, pero no en DataSourceB.
Tulains Córdova
1

Parece que en el nivel superior hay dos tipos: Foo y Bar, y solo tienes dos acciones de nivel superior: findFoo(...)y findBar(...). 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: findFooy findBary un método de B: findFooAuxiliaryInformation. En findFoodeberá 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, y FooAuxData. El acoplamiento entre Fooy FooAuxDataes inherente a los datos de entrada, y no se puede reducir. Pero ese acoplamiento debería aparecer solo en el findFoométodo. Eso es lo mejor que puedes hacer. El requisito se implementa en un solo lugar. Si cambia, debe cambiar ese código.

Kevin Cline
fuente
0

No puedes

Si entiendo correctamente, Fooy Barvengo de dsA. Bars pertenece a Foos.
Preferiblemente, no desea Barasignar s a Foos, a menos que Foohaya sido complementado por Foo.enhancedInfoeso dsB.

Su preferencia por asignar Bars a Foos 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 dsBpueden o no tener información sobre cualquier cosa Fooy que dsBincluso pueden no estar disponibles.

Debe decidir qué tan dura y rápida Foo.enhancedInfoes realmente esa preferencia . Según ese requisito, puede decidir proporcionar un objeto Foo+ Baro no. Permitir Fooque 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 de Foo, Foo.enhancedy Barsus aplicaciones pueden admitir y tendrá su respuesta definitiva.

Hay otras cosas que podría hacer para acercar la Fooinformació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
Al revés: Foo s pertenece a Bar s
fstuijt
@fstuijt Actualizaré mi respuesta en un momento. Fundamentalmente, seguirá siendo el mismo. Debes decidir cómo quieres servir el servidor de Bar + Foo.
0

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.

smp7d
fuente