Come ridurre l'accoppiamento stretto tra due origini dati

9

Ho qualche problema a trovare una soluzione adeguata al seguente problema di architettura.

In le nostre impostazioni (descritte di seguito) abbiamo 2 origini dati, in cui l'origine dati A è la fonte primaria per gli elementi di tipo Foo. Esiste un'origine dati secondaria che può essere utilizzata per recuperare informazioni aggiuntive su Foo; tuttavia questa informazione non esiste sempre.

Inoltre, l'origine dati A può essere utilizzata per recuperare elementi di tipo Bar. Tuttavia, ciascuna barra si riferisce a un Foo. La difficoltà qui è che ogni Barra dovrebbe riferirsi a un Foo che, se disponibile, contiene anche le informazioni come aumentate dall'origine dati B.

La mia domanda è: come rimuovere lo stretto accoppiamento tra SubsystemA.1 e DataSourceB?

    
posta fstuijt 16.11.2012 - 16:11
fonte

5 risposte

3

Ho creato un'applicazione con la stessa architettura di dati alle spalle; disponiamo di un database SQL onsite contenente la maggior parte delle informazioni interne e automatiche e di un servizio cloud di terze parti utilizzato per vendite, gestione degli account, personale sul campo, ecc. L'helpdesk ha bisogno di informazioni da entrambe le posizioni fisiche dei clienti e l'attrezzatura, e l'ho ottenuta da due diverse applicazioni fino a quando non sono intervenuta.

Il lungo e breve è che una fonte di dati deve avere un riferimento ai record dell'altro. Nel nostro caso, i dati cloud di terze parti contengono riferimenti ai dati onsite, perché questa è la disposizione su cui abbiamo avuto il controllo maggiore. Ora, con un ID per un record da entrambe le origini dati, possiamo ottenere dati da entrambi; con un ID cloud, estraiamo il record dal cloud, otteniamo l'ID sul posto e recuperiamo i dati onsite. Con un ID in loco, eseguiamo il polling di entrambe le origini dati basate su tale ID.

Nel mio sistema, non ho reso nessun oggetto un figlio dell'altro nel livello del dominio; qualsiasi utilizzo dei dati da entrambi i negozi deve mantenere due istanze di oggetti. Nessuno dei due è garantito per esistere, ed è per questo che l'ho fatto in quel modo; l'app può funzionare solo con dati cloud, o con dati onsite, o entrambi, con più limitazioni e meno dati.

Tuttavia, non è difficile da cambiare, specialmente se sei sicuro che un lato esisterà sempre; semplicemente includere una proprietà nell'oggetto che rappresenta il lato per cui i dati saranno sempre presenti, cioè del tipo di oggetto che rappresenta il record dell'altra archivio dati. È possibile eseguire una "fusione" più avanzata dei due grafici in uno solo.

Questo tipo di accordo deve necessariamente essere accoppiato a un certo livello. È possibile avere un DAL che può interfacciarsi con entrambi gli archivi di dati, oppure è possibile segmentare i DAL, uno per archivio dati e disporre di un livello superiore come un controller per ottenere i dati da ciascuno e collegarli insieme. Ma, a un certo livello, il tuo programma deve avere la capacità di mettere insieme questi due dati di fonti di dati diversi.

È possibile ridurre l'accoppiamento richiesto nella maggior parte dei casi estraendo i dettagli di esattamente da dove provengono i dati. Se ottieni dati da un servizio web, che ti viene dato come istanze di classi generate, inserisci un convertitore per fare una copia profonda della classe di servizio in qualcosa che controlli, che non dovrà cambiare se i dati fonte fa (solo se lo schema lo fa).

Ora, questa può essere un'impresa enorme; il cloud che utilizziamo ha dozzine di classi di dominio, alcune delle quali hanno centinaia di campi di dati, e - ecco il kicker - potresti facilmente apportare grandi cambiamenti al tipo di dati astratti per adattarsi a un passaggio verso un altro cloud o altro fonte di dati. Per quel motivo, non mi preoccupai; Io uso direttamente il dominio del servizio web generato e ora che il passaggio dal cloud a un sito remoto (ma sotto il nostro controllo) è incombente, i dettagli di cui ancora non conosco, sto semplicemente programmando di cambiare i moduli e codebehinds dell'app, che è dove i dati sono "combinati", per riflettere il nuovo schema e / o gli oggetti dati. È un grande lavoro qualunque sia il modo in cui lo dividi.

    
risposta data 16.11.2012 - 20:47
fonte
4

Un modo per affrontarlo consiste nel creare un'origine dati aggregata che contenga i dati da entrambe le origini dati in un'unica posizione. Un lavoro verrebbe eseguito periodicamente per verificare le modifiche delle fonti A e B e scrivere i "delta" nell'origine dati aggregata. Ciò convertirà due sorgenti di dati strettamente accoppiate in un'unica sorgente di dati coerente.

Diverse cose potrebbero impedirti di adottare questo approccio:

  • La quantità di dati potrebbe essere proibitiva : è necessario eseguire una copia completa di A e B , raddoppiando i requisiti di spazio.
  • I dati saranno live - Ci saranno periodi tra il momento in cui i dati nell'origine sono cambiati e il lavoro di aggregazione l'ha propagato nell'origine aggregata.
  • Devi riconciliare i dati con le fonti originali : il compito di spostare nuovamente le modifiche nelle loro posizioni originali diventa molto più complesso se segui questo approccio.
risposta data 16.11.2012 - 16:33
fonte
1

Sembra che al livello superiore ci siano due tipi: Foo e Bar, e hai solo due azioni di primo livello: findFoo(...) e findBar(...) . Questa è l'interfaccia per il livello I / O.

La tua descrizione delle origini dati implica che ci sono due metodi su A: findFoo e findBar e un metodo su B: findFooAuxiliaryInformation . In findFoo dovrai unire le informazioni da A e B.

Non sono sicuro di quale "stretto accoppiamento" ti riferisci. Esistono tre tipi di dati contenuti nei due set di dati: Bar , Foo e FooAuxData . L'accoppiamento tra Foo e FooAuxData è inerente ai dati di input e non può essere ridotto. Ma quell'accoppiamento dovrebbe apparire solo nel metodo findFoo . Questo è il meglio che puoi fare. Il requisito è implementato in un unico posto. Se cambia, devi cambiare quel codice.

    
risposta data 16.11.2012 - 18:43
fonte
0

Non puoi.

Se ho capito bene, Foo e Bar provengono da dsA . Bar s appartiene a Foo s.
Preferibilmente, non vuoi che Bar s sia assegnato a Foo s, a meno che Foo sia stato integrato da Foo.enhancedInfo che deriva da dsB .

La tua preferenza per l'assegnazione di Bar s a Foo s è ciò che sta creando il tuo accoppiamento stretto. Lo classificherei come una "sfida dei requisiti" che ti sta costringendo verso un particolare percorso.

Quindi le sfide tecniche sono che dsB può o non può avere informazioni su un dato Foo e che dsB potrebbe non essere nemmeno disponibile.

Devi decidere quanto sia difficile e veloce quella preferenza per Foo.enhancedInfo . In base a tale requisito, puoi decidere di fornire un oggetto Foo + Bar o no. Consentire una percentuale non aumentata di co_de da fornire complica la logica e mi dice che la preferenza non è così severa come potrebbe sembrare. Determina quali varianti di Foo , Foo e Foo.enhanced delle tue applicazioni possono supportare e avrai la tua risposta definitiva.

Ci sono altre cose che potresti fare per spostare più vicino le informazioni relative a Bar , e questo potrebbe risolvere alcuni di questi problemi. Il modo in cui è formulata la tua domanda, sembra che tu stia affrontando il problema a livello di oggetto dati e potresti non essere in grado di prendere in considerazione le modifiche al tipo di infrastruttura.

    
risposta data 16.11.2012 - 16:40
fonte
0

Se i dati nell'origine dati B non possono reggersi da soli, probabilmente vorresti migrarlo sull'origine dati A se possibile.

Se sono indipendenti ma correlati, dovresti esaminare virtualizzazione dei dati . Ciò consentirà alle applicazioni di trattare i dati come un insieme (quando appropriato) in modo agnostico. A seconda della piattaforma, probabilmente ci sarà un framework / libreria esistente che può aiutarti a implementarlo.

    
risposta data 16.11.2012 - 16:53
fonte

Leggi altre domande sui tag