Lean Architecture

Mijn eerste reactie op de vraag om ‘Lean Architecture’ in een artikel uit te leggen, is dezelfde wanneer ik gevraagd zou worden om de kleur van een roos uit te leggen. Zonder de roos zelf te beschrijven is de kleur rood slechts RGB FF0000 (of iets in de buurt). Lean Architecture is slechts een ‘perspectief’ in software ontwikkeling en een perspectief van het product zelf.

Er zijn twee perspectieven: ‘architecting’ als werkwoord en ‘architecture’ als zelfstandig naamwoord. Het begrip IT/software/application/etc.-architecture heeft altijd een onduidelijke betekenis in traditionele software ontwikkeling gehad. Echter, in de Agile wereld zijn dit slechts perspectieven van ons product en heeft het begrip weinig betekenis op zichzelf. Eenvoudig gezegd: “Je product is je architecture”. Het maakt eigenlijk niet uit waar we het over hebben, als het zich niet in je product bevindt, dan is het geen architecture. Dit verklaart enigszins de bestaande miscommunicatie en het onbegrip vanuit de traditionele wereld, wanneer ze constateren dat de Agile wereld zich weinig bekommert om allerlei soorten en definities van architectuur.

Hetzelfde geldt voor het werkwoord: architecting. Het is een continu proces van just-in-time besluiten nemen en de directe implementatie ervan; daarmee een onlosmakelijk onderdeel van software ontwikkeling. In de Agile wereld is besluiten nemen geen afzonderlijk proces.

Het woord architecture is ooit geïntroduceerd door te kijken naar het bouw. Inmiddels weten we maar al te goed dat deze vergelijking compleet gefaald heeft. Software is soft, steeds complexer en veranderlijker. De beste softwareproducten hebben een versnelde evolutie. Ideeën aan het begin van de ontwikkeling zijn vaak volledig anders na enkele jaren onderhoud en doorontwikkeling. Diegene die vasthouden aan oorspronkelijke ideeën, ondanks de nood voor verandering, produceren mislukte producten.

De komst van steeds betere technologieën (die eenvoudig te veranderen of vervangen zijn) en ontwerptechnieken, hebben de kosten van verandering sterk naar beneden gedrukt. We zouden zelfs kunnen stellen dat veranderlijkheid in de software wereld het woord ‘architecture’ tot een betekenisloos begrip heeft gemaakt. De beroemde definitie van Grady Booch – dat vaak in de Agile wereld gebruikt wordt – is nog steeds waar: "Architecture represents the significant decisions that shape a system, where significant is measured by cost of change”. Alleen, wat is tegenwoordig nou een echt significant besluit? Veel software producten worden tegenwoordig succesvol in meerdere talen tegelijk geschreven. Oftewel, men heeft niet eens gekozen voor een programmeertaal.

Terwijl architectuur slechts een tijdelijke toestand van een software product is geworden, is architecting belangrijker geworden. Dit is het proces van het voortdurend aandacht schenken aan je complete product van binnen (structuur) en van buiten (vorm). Je software product is je tuin. Je team is trots op deze tuin, plukt daar vruchten van, maar besteed ook substantieel veel tijd aan kleinschalig en grootschalig onderhoud. Hiermee reduceren we de kans op peperdure en nutteloze projecten voor totale vervanging.

In de afgelopen jaren heb ik vele Agile teams mogen meemaken en hun omgang met tuinieren kunnen observeren. Het volgende is mij het meest opgevallen:

 

Team vs. Architect verantwoordelijkheid

Probeer je in te beelden, een keurig onderhouden tuin waar je zelf als tuinier weinig te zeggen hebt over de inrichting van deze tuin. Je voelt je niet verantwoordelijk en iedere echte verbetering vereist overleg met de tuineigenaar. Intussen is er veel druk om te blijven leveren. Dit creëert een ogenschijnlijke onbekwaamheid van het team om zorg te dragen voor de tuin. Het is vaak een jaren durende vicieuze cirkel waar zelfs ontwikkelaars zich niet eens van bewust zijn. Deze onbekwaamheid is de waarheid op een gegeven moment.

Bij een Agile transformatie wordt de verantwoordelijkheid geleidelijk verschoven naar teams. Van de architect wordt gevraagd om als coach, leraar, expert of facilitator op te treden. In de meest succesvolle gevallen is er geen architect meer nodig. In plaats daarvan zijn er meerdere ervaren teamleden die gezamenlijk aandacht schenken aan architectuur.

Het meest opmerkelijke is dat deze samenwerking ook met meerdere teams werkt die samen een groot en complex product leveren. Hoe dit precies werkt, is uitgebreid in [LeSS] beschreven. Deze omschakeling neemt veel tijd in beslag. Er is tijd nodig voor:

  • Cultuurverandering: een ontwikkelaar die breder kijkt dan alleen coderen;
  • Architecten die hun gedrag veranderen, aan teams overlaten, mee-programmeren;
  • Teams die kennis en ervaring moeten opbouwen van cross-cutting concerns, ontwerptechnieken en -raamwerken, schaalbaarheid, etc.;

Uiteindelijk mag het resultaat er ook wezen. Agile teams leveren bijzonder hoge kwaliteit. En nee, dit is geen zeldzaam ras van ontwikkelaars. Het zijn ‘slechts’ ervaren mensen die de passie hebben om de klant en de gebruikers blij te maken.

Een case study hierover is: [HaMIS bij Havenbedrijf Rotterdam].

 

Frameworks zijn geen architectuur

Wanneer ik iemand vraag om de structuur en de vorm van een software product uit te leggen, begint bijna iedereen met de basis van de technologische keuzes. “We gebruikten Spring framework, AngularJS, Hibernate, Oracle database, REST services, etc.” Aan het eind heb ik nog steeds geen idee wat voor software product het is. Waartoe dient het? Welke behoefte vervult het? Welk deel van een business domein gaat het afdekken?

Een minder zichtbaar, maar veel pijnlijker effect is dat we aannemen dat de structuur van het product hiermee bepaald is. Men vraagt zich niet meer af of een database of Spring framework echt nodig is. Om het echt rampzalig te maken: “Gezien de basiskeuzes die gemaakt zijn, kunnen we overgaan het implementeren van features."

De realiteit is dat men hiermee niks relevants heeft bepaald en het zichzelf alleen moeilijker heeft gemaakt. Deze keuzes beperken, en overschaduwen, het gesprek dat vanaf het begin en vervolgens voortdurend plaats moet vinden. Het is een gesprek tussen het team, de stakeholders, de klant en de gebruikers over het business domein, begrippen, het echte werk, het echte ontwerp.

Om Bas Vodde te citeren: “Software development is a knowledge creation process and not a code generation process.” De realiteit is dat we in het begin altijd bijzonder weinig weten. Dit besef resulteert in een volledig andere benadering. De bekende informatie wordt gebruikt om de best mogelijke ontwerpen en architectuur te ‘ontdekken’. Technieken zoals Domain-Driven Design, BDD en TDD helpen enorm om voortdurend te blijven nadenken en zo nodig van gedachten te veranderen. Dit is geen afzonderlijk proces, maar een onderdeel van de normale levering van de gevraagde functies.

Je software structuur straalt dan duidelijk de business behoefte uit in plaats van technologische keuzes en de laatste trends. Een bekend voorbeeld is package structuur. Wanneer de meeste package namen dingen zijn, zoals: “common”, “infrastructure”, “dao”, “environment”, “dashboard”, etc., dan weet ik dat het niet goed zit. De packages moeten veel meer structuur van het business domein laten zien.

Teams kunnen vaak na één sprint van twee weken al een Potentially Shippable Product Increment leveren wanneer ze de meest eenvoudige, maar nette weg kiezen. Dit vereist een fractie van de technologische keuzes die men denkt nodig te hebben.

Fitnesse is een ATDD tool. Een minder bekend verhaal over Fitnesse is hoe deze tot stand is gekomen. Voordat men begon te bouwen, discussieerde het team over welke database ze zouden gebruiken, want dat was immers geëist door de klanten. Die grote hoeveelheid aan test cases moesten in een database gezet worden, toch? Uncle Bob vroeg voortdurend aan het team of het echt nodig was om moeilijk te doen over een database, ondanks de overduidelijke eis. Iedere keer bleef het team de database uitstellen, zelfs na oplevering van eerste versies. Uiteindelijk is die database nooit gekomen. Die eis bleek namelijk geen echte behoefte.

 

Gebruikers dichtbij

Dit brengt ons bij een ontbrekend en een cruciaal aspect van architecting. De gebruikers en belanghebbenden! Alle architecten en teams (Agile en traditioneel) hebben chronisch last van ‘op zichzelf staande architecting’. Op de één of ander manier denkt men besluiten te kunnen nemen zonder samenwerking met de gebruikers en zich daarmee eerst te verdiepen in wat de gebruiker echt nodig heeft. Architecting zonder feedback loops en zonder de eigenlijke behoefte is amateurisme. Ieder genomen besluit moet geankerd zijn in een overduidelijke behoefte die niet uit een document of eis wordt afgeleid, maar door je te verplaatsen in de wereld van gebruikers, beheer en andere belanghebbenden.

De volgende vragen kunnen aan teams gesteld worden om ze uit hun fantasiewereld te trekken:

  • Hoe weet je dat men het dure single sign-on product nodig heeft?
  • Is dit echt het meest eenvoudige wat je kan bedenken?
  • Hoe weet je dat dit gaat werken? Het niet weten is niet erg, mits je de kosten van je experiment over het hoofd hebt gezien.
  • Hoe haal je het in je hoofd om een oplossing voor beheer te bedenken zonder de beheerders erbij te betrekken?

Zoals eerder genoemd, zijn technieken zoals Domain-Driven Design, ATDD, BDD, TDD onmogelijk te beoefenen zonder constante samenwerking met klanten en gebruikers. Deze technieken helpen onze samenwerking een gestalte te geven. Het resultaat van deze samenwerking creëert behoefte voor architectuurbesluiten. Bijvoorbeeld, je bouwt beveiligde communicatie tussen gedistribueerde systemen wanneer feitelijk gevoelige informatie verstuurd wordt. Zorg ervoor dat je service tenminste door één consumer goed gebruikt wordt en dat iemand anders deze ook wil gebruiken, voordat je over de herbruikbaarheid begint te praten. Oftewel, geen hergebruik voor gebruik.

 

Onderscheid tussen vorm en structuur

Een Apple Watch heeft een bepaalde vorm, kleur en kwaliteit die je kan waarnemen. Bijvoorbeeld, de batterijduur van slechts één dag. Over deze uitwendige aspecten kan iedereen meepraten. Als we iets van Apple kunnen leren, is het dat de vorm en de functie niet van elkaar te scheiden zijn. Gezamenlijk bezorgen ze een bepaalde belevenis. Gezamenlijk zijn ze de drijfveer achter de ‘structuur’, oftewel alle inwendige aspecten. Natuurlijk leggen deze inwendige aspecten beperkingen op of zijn ze juist de enabler van vorm en functie (bijv. de grootte van de batterij en de capaciteit), maar ze horen een slaaf te zijn van de vorm en functie.

Al te vaak plaatsen we inwendige aspecten op de voorgrond en maken we het daarmee bepalend of beperkend voor van alles. Terwijl we de gebruikerservaring zien als een bijzaak, iets wat er nog bovenop komt. Ik heb weleens uitspraken gehoord, zoals: “We gaan alvast bouwen, hoewel we nog niet weten hoe de UI eruit komt te zien.”

Dit is… hoe kan ik het netjes zeggen? Je GUI, je interface, je domein staan centraal in de architectuur. En niet welke database, application server of de REST vs. SOAP discussie. Het laatste overschaduwt de functionele aspecten van een interface. Fouten die in de functionele definitie worden gemaakt, zijn heel duur en vaak minder zichtbaar. Een protocol of een applicatieserver vervangen, is aan de andere kant relatief eenvoudig. Het ‘interne structuur gedreven denken’ heeft ons onnodige complexiteit in de Java wereld gebracht, waar we nu nog steeds van herstellen. Herinner je je nog EJB 2 en Core J2EE Patterns nog? Oef, ze bestaan nog steeds. Voor alle duidelijkheid Core J2EE Patterns zijn absoluut geen ‘Best Practices’ en hebben niks met ‘Design Strategies’ te maken.

 

‘Best practices’

De term ‘Best practices’ brengt me tot een diep geworteld probleem dat voorkomt bij veel teams en architecten. In mijn observaties, betekent ‘best practice’ meestal: “we hoeven niet meer na te denken”. Het is immers een ‘best’ practice en wie ben ik om daaraan te twijfelen en kritische vragen te stellen.

Ongeveer 10 jaar geleden was ik architect bij een groot en bekend systeem. Jammer genoeg is mijn opdracht vroegtijdig beëindigd en ik heb het zelf niet in productie kunnen meemaken. Desondanks heeft men keurig gevolgd wat ik op dat moment bedacht heb, wat natuurlijk rampzalig is. Het systeem is uiteindelijk in gebruik genomen. Doordat men mijn adviezen en ontwerpen klakkeloos heeft overgenomen en als ‘best practices’ beschouwde, heeft dat vele problemen veroorzaakt. Is dat mijn schuld? Nee, het was hun schuld dat ze alleen naar een architect luisterden en zelf niet nadachten. De beste les in al mijn jaren is dat ik besefte niet te weten hoe mijn besluiten gaan uitpakken. Daarom ben ik gestopt met fantaseren en gestopt met mezelf architect te noemen. De passie voor het leveren van hoge kwaliteit software producten en anderen hierbij helpen, is echter nooit veranderd.