Usando Bridge e Strategy insieme, la mia idea è corretta / utile?

4

Sto lavorando a un progetto di sito Web per un corso di ingegneria del software. Questo sito utilizzerà un database per memorizzare i dati, attualmente tramite JDBC e MySQL.

Ora la prima cosa che vorrei fare è usare il pattern bridge per disaccoppiare JCBC / MySQL dall'implementazione del sito web, in modo che se in futuro decidiamo di passare a un altro fornitore (come Microsoft Server) , sarà più facile, "solo" cambiare il riferimento alla classe implementor nella classe di astrazione.

Allo stesso tempo, molte delle mie classi usano funzioni molto simili sui databae. Ad esempio, ho tre classi, TripControl, RouteControl e LocationControl, e ognuno di loro ha una classe che usano per parlare al database (TripDB, RouteDB, LocationDB). Quindi stavo pensando, usiamo il modello di strategia, e fallo in modo che TripControl, RouteControl e LocationControl parlino tutti con una classe Context (usando la terminologia del libro qui), e poi usi un oggetto Policy per selezionare quale comportamento usare (TripPolicy per TripDB, RoutePolicy per RouteDB, LocationPolicy per LocationDB), in questo modo si dovrebbe rendere l'utilizzo del DB facile per gli altri sviluppatori (basta scegliere la politica e dimenticare il resto).

Ok, quindi diciamo che uso il modello Strategy, senza Bridge, e passo da MySQL a MS Server (o io uso entrambi), avrei bisogno dei seguenti oggetti policy: TripPolicyMySQL, TripPolicyMS, RoutePolicyMySQL, RoutePolicyMS , RoutePolictyMySQL, RoutePolicyMS, per poter scegliere il tipo di database su cui sto lavorando. Questo rende più difficile per gli sviluppatori implementare le loro classi, e sembra (per me, almeno in questo momento) non molto adatto a un cambiamento.

Se dovessi usare la strategia insieme al Bridge, dovrei avere qualcosa del genere:

Gli sviluppatori hanno solo tre oggetti della politica (LocationPolicy, RoutePolicy, TripPolicy), e usano solo quelli. Quindi, a un livello inferiore, il modello di strategia utilizzerà l'interfaccia di Bridge (ad esempio TripDB sarebbe un ponte per TripDBMySQL e TripDBMS), che nasconderà l'implementazione del database, che potrebbe essere MS Server o MySQL.

Questo avrebbe senso? Immagino che sia più lento a causa di tutte le indirette, ma dovrebbe renderlo più semplice agli sviluppatori e in teoria dovrebbe rendere il sistema più semplice da esplorare.

    
posta Paul 02.01.2017 - 16:25
fonte

3 risposte

2

Hai qui due astrazioni diverse e completamente indipendenti:

  1. che tipo di entità dati stai lavorando con
  2. quale tecnologia di database stai usando per ottenerlo

Il problema con entrambi i tuoi approcci è che quando crei una nuova entità, devi creare un'implementazione per ciascun database. Allo stesso modo, se aggiungi un nuovo database, devi aggiungere un'implementazione per ogni entità. Ciò significa che il lavoro per aggiungere nuove funzionalità alla tua applicazione si ridimensionerà quadraticamente quando dovrebbe essere idealmente lineare.

Avrebbe più senso se le entità dei dati fossero indipendenti dal database e il tuo database ponesse l'aggancio indipendente dall'entità.

Puoi raggiungerlo comunicando attraverso interfacce agnostiche. Tutte le implementazioni di IDatabaseEntity chiamano IDatabaseBridge (che ricevono in fase di esecuzione tramite l'integrazione delle dipendenze) e tutti i metodi di IDatabaseBridge richiedono un IDatabaseEntity e si prevede che funzionino allo stesso modo con qualsiasi classe di implementazione.

Congratulazioni, hai appena reinventato il ORM Wrapper .

    
risposta data 02.01.2017 - 17:37
fonte
2

Valutazione del tuo design

Il disaccoppiamento del codice dipendente dal database dall'implementazione del sito Web è definitivamente una buona idea qui. Tuttavia non è completamente chiaro in che modo si intende utilizzare il pattern bridge:

  • Il schema del ponte riguarda il disaccoppiamento di un'astrazione dalla sua implementazione (usando la composizione), in modo che i due possano variare in modo indipendente. Ma qual è l'astrazione e qual è la sua implementazione qui? È davvero il tipo di disaccoppiamento che stai cercando?
  • Ho l'impressione che il tuo bisogno sia più di separare il livello di presentazione dalla gestione degli oggetti del dominio (Trip, Route, Location). Per questo potresti prendere in considerazione un MVC e MVP o MVVM architettura. Queste sono tutte le combinazioni di diversi modelli di progettazione (ad esempio almeno Observer and Command).

Anche la refactoring della gestione dei dati per riutilizzare comportamenti comuni e isolare il comportamento dipendente dalla tabella di dati è una buona idea. Ma ho seri dubbi sull'uso del modello strategico per questo scopo:

  • L'obiettivo di un modello di strategia deve essere in grado di utilizzare le strategie in modo intercambiabile. Ma non intendi utilizzare RoutePolicy anziché TripPolicy in modo intercambiabile nello stesso contesto (ad esempio RouteControler ), vero?
  • Penso che tu stia cercando il fattorino del comportamento comune in alcuni metodi skeleton e ne modifichi alcune parti. Per questo il modello di metodo del modello sembra più adatto.

Un passo avanti?

Hai analizzato il tuo progetto utilizzando modelli di progettazione generici. Potresti anche considerare i modelli di applicazioni aziendali più specializzati .

Da quanto hai detto, la parte JDBC / MySQL potrebbe finire in qualche tipo di Gateway dati tabella , dove una classe DataGateway base fornirebbe la funzionalità accesso ai dati e le classi TableXDataGateWay derivate potrebbero gestire comandi SQL / comportamento specifici per l'oggetto dominio X . Se in seguito si decide di modificare il database, tutto ciò che è necessario modificare è isolato in queste classi.

Tenendo presente questa logica, potresti ottenere un disaccoppiamento ancora maggiore disponendo di un layer modulo tabella in cima a ciascuna gateway dati tabella, per gestire la logica di dominio (campi calcolati, convalida dei dati, ecc.).

Il tuo server web potrebbe quindi essere strutturato per concentrarsi sulla presentazione e l'interazione dell'utente (implementando un MVC, MVVM o architetture simili, vedi sopra), la parte del modello è qui i moduli della tua tabella.

    
risposta data 02.01.2017 - 18:03
fonte
2

Per prima cosa penso che dovresti prendere seriamente in considerazione se hai davvero il problema che stai cercando di risolvere.

L'architettura che suggerisci permetterà di cambiare il database in modo trasparente, in fase di runtime. Ovviamente questo ha un costo in complessità. Quindi, hai bisogno di essere in grado di cambiare il database in modo trasparente, in fase di runtime?

Se non hai davvero bisogno di passare da un database all'altro, ma vuoi solo evitare di bloccarti in un singolo motore di database, ti suggerisco di separare il livello di accesso ai dati dal livello aziendale. Ciò ti consentirà di riscrivere il DAL in futuro o di introdurre hot-switching dei motori di database, quando sarà necessario .

    
risposta data 02.01.2017 - 18:53
fonte

Leggi altre domande sui tag