Un modo per mantenere l'oggetto tra i livelli disaccoppiato?

1

Penso che questo sia un problema di progettazione comune, ma continuo a grattarmi la testa ogni volta che lo affronto.

Da un lato, abbiamo la nostra API che invia o riceve strutture semplici che possono essere utilizzate da app Web, dispositivi mobili, ecc. Potremmo potenzialmente disporre di più API destinate a dispositivi diversi. Dall'altra parte abbiamo il nostro modello di dominio interno che può o meno corrispondere alle entità dell'archivio dati.

Considera di assumere i seguenti POJO per aiutare la discussione.

@POST
public addBlogPost(BlogPostApi blogPost) { ... }

// api model
public class BlogPostApi {
  ...
}

// domain model
public class BlogPost {
  ...
}

// db model
public class BlogPostEntity {
  ...
}

In primo luogo, potremmo usare lo stesso modello in tutti e tre i livelli. Mentre quella potrebbe essere una soluzione per servizi molto semplici, di solito non è una buona idea poiché tutti gli strati sono accoppiati implicitamente. Quindi, assumerò che vogliamo usare un oggetto modello diverso per 'strato'.

Un approccio che ho visto ampiamente utilizzato è la creazione di adattatori tra livelli. Mentre questo risolve il problema, crea un'esplosione di classi che è necessario mantenere. Nel caso (comune) quando si aggiunge un nuovo campo all'archivio dati che deve essere esposto sull'interfaccia utente, è necessario modificare 3 POJO + 2 adattatori. C'è sempre il rischio di dimenticare di cambiare uno di quelli. Questo processo potrebbe essere leggermente automatizzato, con l'uso di una libreria di mappatura di oggetti.

Un altro approccio che ho sentito è l'uso delle interfacce. Due o più classi implementano la stessa interfaccia che espone i metodi get / set per i campi "comuni". Ciò elimina il rischio di dimenticare di cambiare qualcosa, ma crea un accoppiamento. Inoltre, trovo questo uso delle interfacce errato, dal momento che le interfacce dovrebbero esporre funzionalità.

Sono inclinato verso i mappatori di oggetti. Qualcuno sa di una oluzione per questo problema?

    
posta Dimitrios K. 18.07.2017 - 23:56
fonte

2 risposte

1

Penso che gli adattatori siano l'approccio giusto.

it creates an explosion of classes you need to maintain. In the (common) case when you add a new field to the data store which needs to get exposed on the UI as well, 3 POJOs + 2 adapters need to be changed

Questo è l'effetto di avere un sistema liberamente accoppiato, ma stai solo descrivendo l'effetto negativo dell'accoppiamento libero. Cosa succede quando vuoi aggiungere un nuovo campo all'archivio dati, ma non vuoi esporlo sull'interfaccia utente? Questo design ti consentirà di supportare questo caso d'uso. Supporta anche i casi in cui si desidera memorizzare le cose nel database in modo diverso rispetto a come appaiono nel modello di dominio che è un'esigenza abbastanza comune. Ad esempio, mi piace avere gli ID numerici di auto-incremento su tutte le mie tabelle di database per le chiavi esterne e unire l'efficienza, ma spesso il modello di dominio può utilizzare qualche altro campo univoco come campo di identificazione. Con l'approccio basato su tre modelli, non devo perdere l'id db sul livello del dominio.

    
risposta data 19.07.2017 - 00:40
fonte
0

Anche se l'OP fa riferimento a Java, ho una soluzione basata su C # che si applica direttamente. È possibile utilizzare il modello di progettazione MVC per disaccoppiare completamente l'interfaccia utente, il BL e il DAL tramite interfacce e adattatori. Ho implementato una soluzione del genere con il pacchetto GPS.SimpleMVC su GitHub. Puoi leggere ulteriori informazioni al riguardo nel link .

Ora, la carne e le patate provengono dall'uso delle interfacce per definire le viste e i dati / azioni associati a tali viste. È possibile scegliere di accoppiare le viste a Modelli o disaccoppiare le viste tramite la logica nei controller. I controllori accettano istanze di viste come input e registrano agli eventi esposti da tali viste. Ad esempio, se è necessario comunicare al controller di caricare alcuni dati, si utilizza un delegato (evento) per inviare un segnale al controller per eseguire alcune operazioni. Il controller è quindi responsabile della creazione dei modelli. I Modelli sono responsabili dell'esposizione di un DAL tramite un'interfaccia comune. All'interno del POCO i modelli sono codice per caricare un adattatore in base alla configurazione utilizzando Iniezione di dipendenza. L'adattatore ha il codice per l'accesso ai dati.

Questo disaccoppia completamente i tre livelli dai dettagli di implementazione l'uno dell'altro. La strong coerenza deriva dall'uso appropriato delle interfacce.

    
risposta data 19.07.2017 - 02:59
fonte

Leggi altre domande sui tag