Come si può separare un monolite in librerie gestite da domini senza duplicare interfacce e mantenere semplici le dipendenze?

4

Sto lavorando a un progetto con servizi web e ho strutturato cose in cui:

Di recente ho studiato i microservizi . Con il senno di poi, vorrei dividere il servizio in più servizi ciascuno che copre un dominio specifico del business. Cosa avrei dovuto fare con la biblioteca? Sto pensando che potrei:

  • Conserva la libreria monolitica utilizzata da tutti i servizi
  • Dividi la libreria in più parti (di nuovo, in base ai domini aziendali)
    • Ogni libreria include tutte le interfacce con cui interagisce (il che significa ridondanza tra le librerie)
    • Librerie di colla che coprono lo spazio o il confine tra due domini

Non mi piace la libreria monolitica, ma non riesco a decidere come avrei dovuto dividerlo. Non mi piace l'idea di duplicare il codice del modello, ma non mi piace l'idea delle librerie di colla neanche - sembra non intuitivo; non è semplice come dovrebbe essere.

Come si può separare un monolite in librerie gestite da domini senza duplicare interfacce e mantenere le dipendenze semplici?

Al momento, sto pensando:

  • Una libreria a colla singola contenente tutte le interfacce e la logica aziendale
  • Numerose librerie guidate da domini contenenti implementazione e accesso ai dati
  • I servizi si traducono principalmente in e dalla colla

È questo il miglior compromesso? Sono preoccupato che la libreria di colla sia solo un mini-monolite.

    
posta ricksmt 06.05.2016 - 19:34
fonte

3 risposte

4

Mi sembra che la tua domanda sia divisa in due parti. Il primo riguarda la duplicazione delle interfacce. Il secondo sulle dipendenze.

In primo luogo, duplicazione delle interfacce. Probabilmente vuoi duplicarli nel caso che stai descrivendo.

Una buona regola generale quando si rompe un monolite è mantenere i propri confini chiaramente definiti. Se si dispone di due domini, può essere contro-intuitivo tenere presente che qualsiasi oggetto di dominio dato deve essere modellato in un modo che è univoco per il dominio.

Ad esempio, se hai un'interfaccia cliente, ICustomer, e hai due domini, ordini e fatture, sebbene sia gli ordini che le fatture utilizzano qualcosa chiamato cliente, spesso è meglio definire l'interfaccia due volte rispetto a provare forzare una singola interfaccia (di solito a causa di un fraintendimento di DRY). Questo perché un cliente dal punto di vista del dominio dell'ordine è una bestia molto diversa rispetto a un cliente dal dominio Fatture. Potrebbe sembrare intuitivo che sia gli ordini che le fatture condividano la stessa interfaccia ICustomer. Ma in verità, probabilmente no. Un cliente in un dominio di ordine è molto diverso da un cliente in un dominio di fatturazione e cambierà per ragioni molto diverse.

Quindi, se vuoi dividere il tuo progetto in micro servizi basati sul dominio, crea librerie attorno a ciascun dominio. Non essere così preoccupato di come riusare il codice (o altre risorse) attraverso i domini, ma quanto è facile cambiare il codice in un dominio senza rompere il codice in un dominio non correlato.

Secondo, dipendenze. Questo per lo più risolverà se stesso dopo aver risolto il problema di cui sopra. Mantenere le dipendenze semplici è una questione di mantenere le dipendenze isolate nel loro dominio appropriato, e quindi spingere le interfacce per le dipendenze più generalizzate nelle librerie comuni di base.

    
risposta data 06.05.2016 - 20:28
fonte
2

Penso che tu voglia inversione di dipendenza , dove il codice di "livello superiore" (come il dominio) definisce le interfacce che funzionerà contro, e quindi richiede che chiunque la utilizzi possa in qualche modo fornire implementazioni adeguate.

Metaforicamente, stai assumendo una celebrità prima donna: si esibiranno, ma stabiliscono che all'aeroporto si aspettano di essere accolti da una limousine nera con cioccolatini alla menta, acqua in bottiglia e un cucciolo. Probabilmente non troverai nessun servizio di limousine, negozio di dolciumi, pet-store, ecc. Che tutti di questo, ma puoi certamente incollarli insieme. (Basta che il cucciolo non abbia del cioccolato.)

Tornando al mondo reale, attualmente ho un progetto che funziona in questo modo:

  1. Libreria di domini
    • Dominio logico (duh)
    • Fornisce interfacce come FooRepository o BarSerializer o BulkDataStorer .
    • È codificato contro quelle interfacce, si aspetta che chi lo usa possa iniettare implementazioni concrete. (Nei test unitari, fornisci il tuo.)
  2. Biblioteche di supporto indipendenti, ad esempio:
    • Uno strumento ORM di terze parti
    • Una libreria client indipendente per un webservice interno
    • Librerie per materiale di livello Web o MVC
  3. L'applicazione:
    • Porta tutto insieme
    • Forse ha un framework di Iniezione delle Dipendenze
    • Fornisce adattatori e facciate concreti per colmare il divario tra le interfacce del dominio e le classi concrete che potrebbero portare a termine il lavoro.
    • Esempio: un'implementazione molto sottile di FooRepository che sfrutta l'ORM di terze parti.

Ora, se qualcosa in # 3 diventa troppo grande, hai la possibilità di dividerlo nella sua libreria, ma prima di fare le "librerie di colla" darei un'occhiata lunga a lungo se sono in realtà contesto specifico per un'applicazione e quanto sarebbero davvero riutilizzabili.

    
risposta data 06.05.2016 - 19:52
fonte
0

Uno dei vantaggi dei microservizi è che ciascun microservizio può evolversi in modo relativamente indipendente dall'altro, a causa di un accoppiamento più lento.

Mantenendo la biblioteca del monolite e riutilizzandola in tutti i microservizi non entrerebbe nella logica, perché avresti molte più dipendenze che dovresti avere. L'unico vantaggio che otterrebbe da un tale approccio pseudo-microservizio sarebbe una distribuzione più semplice dei tuoi servizi, quindi forse una migliore scalabilità.

Un altro punto importante da considerare è che ogni microservizio dovrebbe essere responsabile dei propri dati . Avere molti microservizi utilizzando un singolo database monolito avrebbe in qualche modo perso il punto. Ciò suggerisce che ciò che è l'accesso ai dati di dominio per un microservizio, dovrebbe essere la richiesta del servizio di dominio per un altro.

La libreria di colla per le interfacce è un primo passo per disaccoppiare un po 'di più i servizi. Tuttavia penso che eviterebbe comunque l'evoluzione indipendente di ogni microservizio. Preferirei optare per questa alternativa:

  • Librerie di interfaccia basate sul dominio
  • Implementazione di microservizi, segmentati per dominio (non necessariamente in una libreria), ma utilizzando la libreria di interfaccia corrispondente.
  • Librerie di consumo dei servizi basate sul dominio a seconda delle rispettive librerie di interfaccia (libreria distinta per ogni dominio / microservizio)
  • Le applicazioni che utilizzano i microservizi potrebbero riutilizzare queste librerie di consumo dei servizi, ma solo quelle necessarie.

Il vantaggio di questo approccio rispetto alla libreria di colla è che:

  • le dipendenze tra i microservizi sono esplicite (uso delle librerie che consumano) e ridotte al minimo.
  • La dipendenza
  • tra consumatori e servizio è isolata nella libreria dell'interfaccia.
risposta data 06.05.2016 - 20:21
fonte

Leggi altre domande sui tag