High Cohesion, Low Coupling, Encapsulation, Modularity, Separation of Concern zijn voor mij de belangrijke architectuur principes om een aantal kwaliteit aspecten van software te realiseren, zoals onderhoudbaarheid, herbruikbaarheid, aanpasbaarheid, vervangbaarheid, security, etc.

In dit artikel maak ik een eerste stap hoe je deze architectuur principes kunt toe passen in OutSystems. Waarbij ik begin met logische componenten en deze gaandeweg naar fysieke componenten (modules in OutSystems) omzet.

Logische componenten en lagen

High Cohesion

Dit is voor mij de eerste van de 2 belangrijkste architectuur principes. Deze bepalen namelijk voor het grootste gedeelte hoe je je software op deelt in logische componenten. High Cohesion hoe kan ik mijn entiteiten groeperen die logisch bij elkaar horen. Dit kan op meerdere manieren. Op basis van het proces waarin ze gebruikt worden (bijv. een order proces). Of op basis van business functie (bijv. sales, productie, marketing, inkoop, …). Het is niet verstandig deze te groeperen op basis van organisatiestructuur. Een afdeling kan meerdere business functies gebruiken. Een business functie kan door meerdere afdelingen gebruikt worden. De business functies zullen niet snel wijzigen, terwijl dit bij een organisatiestructuur vaker het geval is. Gedeelde entiteiten zet je in een apart component (bijv. adres).

Low Coupling

De 2e zeer belangrijke architectuur principe. Hoe zorg ik ervoor dat een wijziging in een component niet meteen betekend dat ik alle componenten moet aanpassen. De eerste stap is een logisch componenten model. De volgend stap is bepalen kijken naar de use cases/user stories. Elke user story resulteert in een gebruikers functionaliteit/dienst die je moet leveren, die hoort bij een logisch component waarvan een entiteit getoond, aangemaakt, gewijzigd of verwijdert moeten worden. De diensten/functionaliteit die vanuit een gebruikers dienst of tussen logische componenten aangeroepen wordt is een business functionaliteit/dienst. Dit resulteert in extra logische componenten.

Logische lagen

Om hergebruik, uitwisselbaarheid, onderhoudbaarheid, aanpasbaarheid te vergroten is het opdelen van je software in lagen de volgende stap. Belangrijk hierbij is niet te veel lagen te gebruiken en vast te leggen hoe de communicatie tussen de verschillende lagen mag lopen. Ik deel mijn software meestal logisch in 3 lagen in. Een presentatie laag (UI), een domein laag(met business logica) en een data laag,. De communicatie/aanroepen zijn standaard van boven naar beneden en alleen de componenten in de business logica laag mogen elkaar aanroepen. Hierbij mag er geen laag overgeslagen worden. De enige uitzondering die ik maak is het aanroepen van de data laag vanuit de UI voor lees acties(vanwege performance)

De UI laag kun je nog onderverdelen in 2 sub lagen, presentatie logica, en taak specifieke logica. Ook de domein laag kun je nog verder onderverdelen, met als extra sub laag de generieke business logica over meerder domeinen zonder eigen entiteiten.

Fysieke componenten en lagen (OutSystems Modules)

Het bepalen van het logische model is in principe onafhankelijk van de gekozen implementatie. Hoe vertalen we dit logisch model nu naar een model dat we binnen OutSytems kunnen implementeren.

Lagen

Vanuit de OutSytems architectuur kennen we drie lagen. UI, Core, Foundation. De presentatie laag kunnen we 1 op 1 mappen met de UI laag in OutSystems. De domein laag map je de Core laag. De data laag zit in OutSystems. De communicatieregels zijn van boven naar beneden en binnen de Core laag ook zijwaarts. Dus van de UI laag naar de Core laag, naar het OutSystems Platform. De uitzondering voor het overslaan van de Core laag zijn de lees acties (aggregaties in OutSystems).

In OutSystems blijft er nog een laag over die we niet gemapt hebben aan het logische model, de Foundation laag. In deze laag zitten de componenten die niet direct met business functionaliteit te maken hebben, maar meer met techniek (technische integratie met andere systemen, UI bouw blokken, functies, etc).

Encapsulation

Vanuit software architectuur is dit een methode om ervoor te zorgen dat als ik in een component iets wijzig niet meteen alle gerelateerde componenten moet wijzigen en hiermee de Low Coupling vergroot. Hoe scherm ik de logica in een domein component af.

Binnen OutSystems kun je dit op 2 manieren bereiken. Zorg dat je Core Modules alleen via public actions aangeroepen kunnen worden, op het moment dat je de aanroep zelf niet aanpast kun je alles binnen het component wijzigen zonder dat er andere modules aangepast hoeven te worden. De 2 optie is dat je modules alleen via API’s aangeroepen kunnen worden. Dit is een meer service georiënteerde aanpak en zie je terug in ODC.

Separation of Concerns

Door je oplossing onder te verdelen in lagen en modules en deze onafhankelijk van elkaar te maken, kun je de verantwoordelijkheid verdelen. Op laag niveau een verschil in front-end en back-end specialisten. Daarnaast op domein niveau (binnen de Core laag) wie is eigenaar van welke business functie. Vanuit gebruikers perspectief wie is er verantwoordelijk voor een specifiek gebruikersinterface en taak specifieke functie.

Wat er nog overblijft is “packaging”, binnen OutSystems het combineren van verschillende modules in een applicatie die uitgerold kan worden. Ik volg hiervoor een aantal regels. Combineer geen modules die een verschillende business eigenaar of business sponsor hebben. Combineer alleen modules die dezelfde life-cycle hebben. Op het moment dat verschillende modules afhankelijk zijn van andere modules met een verschillende eigenaar of andere life-cycle is het verstandig deze in verschillende applicaties onder te brengen.

 

#outsystems #softwarearchitecture #odc #lowcode

Marc Wetters

Senior Software Architect at LowQode