Fælles for de agile udviklingsprocesser er, at de lægger op til at vi leverer små forretningsværdiskabende stykker af funktionalitet. Når leverancen fejler, er det tit på grund af eksisterende kompleksiteter – domænet, datamodellen eller infrastrukturen forhindrer os i at nå målet.
Principper som DRY (Don’t Repeat Yourself) gør at vi ivrigt genbruger og skaber bindinger og samtidigt maler vi os selv op i et hjørne hvor ændringer som ringe i vandet giver sideeffekter i hele systemet.
Lagdelt arkitektur er der det starter. Vi laver en model der kan løse alle vores problemer og arbejder ud fra denne. Problemet er, at vi i lang tid er blevet opdraget til at dele vores arkitektur horisontalt men aldrig har haft fokus nok på den vertikale opdeling.
Vi ved allerede at vores samarbejde bør afspejle denne opdeling, som Per Jessen Schmidt var inde på i starten af året. Men hvis vi kan skabe en arkitektur der også formår at afspejle denne opdeling kan vi måske opnå endnu mere agilitet.
Idéen er, som Ayende også tidligere har beskrevet, at vi deler vores projekter op i en række helt isolerede koncepter. For en webshop kunne det fx. være ordrer, kunder, lager osv.
Hvert af disse områder vil så indeholde de nødvendige lag – en projektstruktur kunne se sådan ud:
-
Ordrer
- Model
- Queries
- View
- Controller
- ViewModel
-
Kunder
- Model
- Queries
- View
- Controller
- ViewModel
Bemærk at i denne model er alle de traditionelle lag samlet i et projekt. Model, ViewModel og Controller til at understøtte MVC-mønstret, model til domæne og queries til forespørgsler mod en underliggende database – der kunne også være tale om et separat grænseflade-projekt med underliggende model-projekt. Det ændrer ikke så meget:
-
UI
-
Ordrer
- View
- Controller
- ViewModel
-
Ordrer
-
Domain
-
Ordrer
- Model
- Queries
-
Ordrer
Hvordan de vertikale snit bestemmes er individuelt. Fra domain-driven-design, har vi begrebet rod-aggregat som er en klasse der bestemmer livsforløbet for en række andre klasser. I ordre-eksemplet kunne der være tale om en ordre med tilhørende linjer. Koncepter indeholder typisk én af disse rod-aggregater.
Det vigtige er den proces vi skal igennem når ny funktionalitet skal tilføjes – hvert koncept kan indeholde mange features og her gælder det om at nye features i så stort omfang som muligt kun giver tilføjelser og ikke ændringer – kendt fra SOLID som open-close princippet. I objektorienterede systermer skal vi ideelt set blot tilføje en klasse.
Næste spørgsmål er så hvordan kommunikation imellem koncepter foregår. Der kan være tale om direkte kald, domain-events eller publish-subscribe. Hvis koncept-snittet er ført hele vejen ud til grænsefladen kan kommunikationen foregå der. I traditionelle web-apps kan der slet og ret være tale om parameteriserede hyperlinks mellem koncepterne, eller i single-page-applications kan der bruges events eller en af de mange pub/sub-frameworks.
Arkitektur med isolerede koncepter, SOA, domain driven design med rod-aggregater – det hele handler om at vi skal have lav kobling. Men øvelsen er ikke nem – frameworks, genbrugsfanatisme, delte datastrukturer er alle forhindringer. Men vi bør stadig stræbe efter det. Det betaler sig når vi i morgen skal vedligeholde den software vi har skrevet i dag.