Porta chiarezza al tuo monolite con Contesti limitati

Guarda il video di questo discorso da ElixirConf 2017 sotto

Le applicazioni monolitiche sono fantastiche quando inizi a costruire la tua azienda, ma con il passare del tempo diventano difficili da mantenere. Queste basi di codice, man mano che crescono, diventano facilmente Grandi palle di fango.

Indiana Jones Rock

Quando si costruiscono applicazioni di grandi dimensioni in framework come Rails, i principi di progettazione della convenzione-over-configuration che hanno reso Rails una tale gioia da usare iniziano a intralciarsi quando l’applicazione cresce in ambito. Si può sperimentare gli stessi dolori pure se:

  • Il refactoring è difficile e noioso, perché i metodi e le classi dipendono da troppe altre classi
  • Hai un elenco sempre crescente di oggetti di business che sono difficili da tenere nella tua testa. Infatti, nessuno sembra essere in grado di comprendere il sistema come un insieme coerente
  • modificare il codice in un’area di codice conduce imprevisti e indesiderati effetti collaterali in altre aree del codice, perché è facile chiamare globale di servizi e di oggetti

Nella nostra ultima chiacchierata insieme, abbiamo discusso lo sviluppo di un Linguaggio di connettività insieme con esperti di business e il vostro team di sviluppo per aiutare il vostro team di lavorare insieme. Oggi, ci accingiamo a costruire su questo introducendo nuovi strumenti di Domain-Driven Design (DDD). Quindi, introdurremo una nuova struttura di cartelle per le tue app Rails, preparandole per un futuro in cui l’applicazione sia meno accoppiata e più coesa. Cominciamo!

Parliamo di domini

Un principio chiave in DDD è che il software che costruisci deve rispecchiare da vicino il dominio (aziendale) dell’organizzazione che lo costruisce. Quindi, abbiamo bisogno di fare alcuni compiti a casa per capire il dominio di business del software.

Un dominio è ciò che fa l’azienda e il contesto di come lo fa.

Rivisitiamo il nostro esempio Delorean dal post precedente. In esso, la società è commercializzata come Uber per viaggi nel tempo. Quindi, il suo “dominio” (il “cosa fa”) è il Ridesharing del viaggio nel tempo. Nel dominio è incluso anche il “come” di come lo fa – collaborando con i conducenti che possiedono veicoli Delorean che viaggiano nel tempo con i passeggeri che vogliono fare viaggi nel tempo.

Per ottenere più sfumature nel dominio aziendale, DDD introduce un altro concetto, chiamato Sottodominio:

Un sottodominio rappresenta i gruppi o le unità più piccole dell’azienda che collaborano giorno per giorno per raggiungere gli obiettivi dell’azienda.

Delorean è divisa in diversi team all’interno dell’azienda. Diamo un’occhiata a due di loro, e vedere di cosa sono responsabili:

Viaggio di un team di Piattaforma Operazioni di Finanza di squadra
Missione Progettazione e supporto dei sistemi che itinerario viaggi e collegare i driver passeggeri Gestire i sistemi che coinvolgono istituzioni finanziarie e processori di carte di credito
Responsabilità
  • Collegare i passeggeri di driver
  • il Percorso del driver per la loro prossima destinazione
  • Avvisare i passeggeri che arrivano driver
  • Avviso i driver nuovi passeggeri
  • Elaborare i pagamenti ai conducenti
  • Mantenere la cronologia delle transazioni a livello di sistema per il controllo
  • Creare rapporti finanziari
  • Elaborare le spese della carta di credito ai passeggeri

Ognuno di questi due gruppi animano una responsabilità aziendale, o sottodominio. Diamo loro il nome di Ridesharing Experience ed e-commerce, rispettivamente.

Ora abbiamo un’illustrazione generale del business e due delle sue unità che lo aiutano a funzionare nel giorno per giorno. Il dominio e il sottodominio sono modi per modellare lo spazio problematico della tua azienda e come agisce per soddisfare questi ruoli. È probabile che il grafico dell’organizzazione aziendale rifletta da vicino i sottodomini della tua attività. Nel mondo reale, le delineazioni possono essere meno chiare: i team possono essere responsabili di sottodomini multipli e sovrapposti.

Riempiamo questo diagramma con alcuni altri sottodomini nel business Delorean:

  • Sottodominio Assistenza clienti: risoluzione dei ticket di assistenza clienti in arrivo tramite e-mail
  • Sottodominio marketing: gestione di campagne di email marketing e marketing codici coupon
  • Identità sottodominio: Come il sistema tiene traccia di ogni utente e delle sue informazioni di identificazione

Contesti Delimitati nella soluzione di spazio

Questo diagramma di fronte a noi ora riflette gli obiettivi di business dell’azienda, diviso in unità logiche che (si spera) realizzare i propri obiettivi nel mondo reale. Ora ci accingiamo a sovrapporre i sistemi software che realizzare questi obiettivi su questo diagramma. Questi sistemi software sono descritti come Contesti limitati:

Un contesto limitato è un sistema che soddisfa gli obiettivi del business nel mondo reale.

Tutti i nostri sistemi software (come un servizio web o un’app web) che operano come istanze concrete nel mondo reale sono considerati Contesti limitati.

Tecnicamente parlando, il Contesto limitato in DDD-speak è un limite specifico all’interno del tuo dominio che il tuo Glossario dal tuo linguaggio Onnipresente può applicare solo – l’idea è che sottodomini diversi possono avere definizioni di termini concorrenti o contrastanti. Questo post non approfondirà le sfumature linguistiche del contesto limitato. Per ulteriori letture, vedi la spiegazione di Martin Fowler sui contesti limitati.

Ora si dà il caso che a Delorean, tutti questi sottodomini sono implementati in un unico sistema – una grande palla di fango Rotaie Monolite. Disegneremo una scatola blu attorno ai sottodomini le cui funzioni sono implementate dal sistema software. In questo caso, inizieremo con il nostro monolite Rails di cui sopra:

Dal momento che è il monolite, fondamentalmente fa tutto – e così qui, sta mangiando tutti gli altri sottodomini nel diagramma.

Non dimentichiamo – abbiamo alcuni altri sistemi software che non abbiamo modellato qui. Che dire di tutte le belle integrazioni di terze parti che l’azienda utilizza? Anche questi sono sistemi software. Li disegneremo come scatole blu.

A proposito – quello che abbiamo disegnato qui è una mappa di contesto – un diagramma che mescola obiettivi di business e implementazioni concrete di sistemi software. È utile per valutare la posizione del terreno dei tuoi sistemi software e visualizzare le dipendenze tra i team.

Ora, questo è ragionevole e pulito, ma viviamo nel mondo reale, e il software del mondo reale raramente esce in modo coerente e coerente. Se hai creato la tua app Rails seguendo le sue convenzioni predefinite, la tua app non ha internamente i raggruppamenti necessari per visualizzare la tua app nei suoi componenti costitutivi. In realtà, la base di codice Delorean assomiglia a qualcosa di più simile a questo:

Il punto è – Rails non impone alcun vincolo organizzativo sui nostri sistemi software – il che significa che le business unit logiche (i nostri sottodomini) che suggeriscono interfacce disaccoppiate-non si materializzano nel codice, portando a confusione e complessità crescente con il passare degli anni.

La grande idea: organizzare il codice Rails in moduli per sottodominio aziendale

Anche se le classi Ruby nella tua applicazione probabilmente vivono nello spazio dei nomi globale, possono essere facilmente pizzicate nei moduli. Il nostro obiettivo è creare gruppi logici di codice di dominio che possono essere isolati in componenti autonomi.

In effetti, uno degli obiettivi dei progetti basati sul dominio è quello di avere una mappatura one-to-one da un sottodominio a un contesto limitato.

OK, cosa significa? Entriamo in alcune raccomandazioni, insieme ad esempi.

Inverti le strutture di cartelle in un raggruppamento piatto orientato al dominio

Potresti ricordare che le seguenti convenzioni Rails ci portano alle gerarchie di cartelle che raggruppano le classi per ruoli:

Spostiamo tutto in una nuova struttura di directory: raggruppiamo come funzionalità per dominio, invece. Inizieremo con una prima variazione, che chiamerò un raggruppamento orientato al dominio piatto.

Modulizza classi

Successivamente, ti consigliamo di modulizzare le classi da quello che erano prima. Poiché la classe Driver rientra nel dominio Ridesharing, la aggiungeremo a un modulo Ridesharing:

Ti consigliamo di farlo per ogni classe che si sposta nella struttura di directory piatta app/domains.

Riferimento i modelli associati dal nome completo della classe

Inoltre, avrai bisogno di cambiare il vostro modello ActiveRecord associazioni di riferimento per la classe con la sua piena, modulized percorso:

Tenere il controller aggiornato su dove trovare il loro nuovo modulized vista

avrete anche bisogno di inserire questo piccolo bit per consentire percorsi dal controller so dove cercare il punto di vista:

Ecco il bello: non È necessario spostare tutto il codice in una sola volta. Puoi scegliere un piccolo dominio nella tua applicazione, l’area più matura del tuo codice o l’area che hai la migliore comprensione in giro, e iniziare a spostare le sue preoccupazioni in una singola cartella di dominio, il tutto lasciando il codice esistente a riposo fino a quando non è pronto a muoversi.

Ora, abbiamo fatto alcuni piccoli passi per raggiungere la chiarezza architettonica nella nostra applicazione. Se guardiamo ora, le nostre strutture di cartelle modulari ci hanno aiutato a raggruppare il nostro codice in questo modo:

Sotto il cofano, la nostra app potrebbe essere più simile a questa:

Cosa funziona bene con questo approccio?

  1. C’è meno rumore in ogni directory del file – dal raggruppamento, come i file dal dominio specificità, abbiamo una natura organizzativa punto
  2. Le entità che rimangono in ogni cartella del dominio sono altamente coesivo che probabilmente tendono naturalmente a comunicare con gli altri e compaiono naturalmente con l’altro
  3. Entità che non appartengono insieme sono ora separati (looser accoppiati)
  4. Se si dispone di team di ingegneria che opera lungo Sottodominio-responsabilità, questi tecnici sono ora in grado di lavorare in più snella, isolato moda. Looser accoppiamento permette a queste squadre di modifiche con la certezza che essi non introdurre regressioni o conflitti di unione indietro per il codebase
  5. La fase è ora impostata nel lungo periodo per iniziare a muoversi di ognuno di questi le cartelle del dominio in un software indipendente di servizio (più su che in un futuro post del blog)

Se volete ulteriori indicazioni in questa struttura di cartelle, ho sviluppato un’applicazione di esempio che espone questo dominio-oriented struttura di cartelle: http://github.com/andrewhao/delorean. Date un’occhiata e fatemi sapere cosa ne pensate.

Cosa abbiamo imparato?

Nel nostro tempo insieme, abbiamo imparato a conoscere i concetti di progettazione domain-driven intorno domini e sottodomini. Abbiamo imparato a visualizzare i nostri sistemi software come Contesti delimitati su una mappa di contesto, che ci ha mostrato le aree del sistema che appartengono insieme come parti coerenti.

Terminando con una nota pratica, abbiamo illustrato come i file e le cartelle Rails potrebbero essere “invertiti” e reimmaginati come raggruppamenti domain-first.

Nel mio prossimo post, continueremo la nostra discussione in un prossimo post sul blog su come disaccoppiare ulteriormente il nostro codice Rails orientato al dominio con gli eventi di dominio e alla fine ci faremo strada nella terra dei microservizi.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.