5 minute read

Of: van Agile-principes naar hotspots in Fabric

Inleiding — waarom dit artikel

In veel organisaties wordt nagedacht over architectuur.
Lagen worden ingedeeld. Code-eisen worden bedacht. Lange meetings worden uitgezeten.
Daarna is het de bedoeling dat iedereen volgens die plaatjes gaat werken.

In de praktijk blijkt dat lastig.
Zeker wanneer je een bestaande situatie moet aanpakken.

Iedereen hoopt op een greenfield: een blanco papier, geen historie, alles netjes opgezet.
Maar zelfs dan blijkt na drie maanden dat de werkelijkheid weerbarstig is.
Nieuwe vragen dienen zich aan, aannames blijken onvolledig en de eerste shortcuts sluipen erin.

Dus hoe kun je in je alledaagse werk toch gericht blijven op architectuur?

Agile — hulpmiddel, geen hoofdzaak

Wat je vaak hoort, is dat je dan volgens Agile moet gaan werken.
Er komen sprints, epics, Jira. Iedere dag lijkt er wel een ceremonie te zijn.

Maar dat is niet de kern van Agile.

De bedoeling van Agile is dat je met kleine stappen en snelle feedback
in de goede richting blijft werken.
In essentie volgt het de wetenschappelijke methode:

theorie → experiment → leren

Of simpeler:
ik denk, ik probeer, en ik weet nu beter.

Het probleem ontstaat wanneer het proces de hoofdzaak wordt.
Wat bedoeld was als hulpmiddel, wordt een doel op zich.
Dan krijg je het gevoel vast te lopen in procedures
en krijgt Agile een slechte naam binnen de organisatie.

Terwijl Agile zelf zich waarschijnlijk afvraagt:
wat heb ik hier eigenlijk mee te maken?

Van principe naar praktijk: Business Intelligence

Maar laten we eens kijken naar Business Intelligence.

Er is een nieuw project.
Er wordt gezegd: “We willen meer inzicht in de sales.”

Je hebt goed gekeken naar Agile en je weet dat je nu een story nodig hebt.
Een persona, een wat en een waarom.
Dus je komt met de volgende:

Als product manager wil ik de sales van vorige week zien,
want dan kan ik mijn inkoop voor volgende week bepalen.

Ok. Je weet nu wie het wil en waarom.
Maar de wat is hier onduidelijk.

Sales. Netto, bruto, hoeveelheid?
Hoe zit het met retouren?
Moeten bestellingen die nog niet geleverd zijn meetellen?

Wat er vaak gebeurt, is dat je daar gaandeweg achter komt.
Feedback tijdens het testen.
“Nee, die hoort er niet bij!”

En omdat de deadline dichtbij is, zet je een extra filter in de measure.
Anderen die dezelfde sales-measure gebruiken doen dat ook.
En dan kan die measure er ineens zo uitzien:

Total Sales :=
SUMX (
    FILTER (
        Sales,
        Sales[Status] <> "Cancelled"
            && Sales[OrderType] <> "Return"
    ),
    ( Sales[Quantity] * Sales[UnitPrice] )
        - Sales[RebateAmount]
)

Soms is er nog meer flexibiliteit nodig
en gebruik je onafhankelijke tabellen als parameters
die het gedrag verder verfijnen.

Maar nu is deze measure een hotspot geworden:
een ingewikkelde bouwsteen waar veel logica samenkomt
en die ook nog eens vaak gewijzigd wordt.

Dit is typisch zo’n plek waar complexiteit en wijzigingsfrequentie elkaar versterken.

Complexiteit verplaatsen in plaats van opstapelen

Maar goed. In de measure zit nu de businesskennis.
De volgende stap is niet om die verder uit te breiden,
maar om te kijken hoe je die kunt opdelen.

Onze manager wilde inkoop plannen.
In de definitie ging het om alle oorspronkelijke verkopen.
Retouren moesten er niet af.
Of een klant later iets terugstuurt maakt niet uit voor de inkoopplanning.

Dus je definieert iets als Bruto verkocht aantal.
Met als betekenis: alle hoeveelheden
die ooit bij een klant terecht zijn gekomen.

We willen de complexiteit verdelen.

De zilverlaag is de plek waar je businesslogica vastlegt.
Niet omdat dat “moet volgens het plaatje”,
maar omdat het de plek is waar definities expliciet worden.

Daar zet je in een notebook bijvoorbeeld het volgende neer:

SELECT
    *,
    CASE 
        WHEN Status <> 'Cancelled' THEN 1 ELSE 0 
    END AS IsValidSale,
    CASE 
        WHEN OrderType <> 'Return' THEN 1 ELSE 0 
    END AS IsGrossSale
FROM RawSales

Hier leg je vast wat iets is, niet hoe het later gebruikt wordt. Per regel wordt nu expliciet gecodeerd of deze meetelt als geldige verkoop en of deze meetelt als bruto verkoop.

Het voordeel daarvan zie je direct terug in de measure:

Total Gross Quantity :=
CALCULATE(
    SUM(Quantity),
    IsGrossSale = 1
)

Principes als houvast

Ontwerpen en bouwen is nooit absoluut.
Er zijn altijd compromissen. Je wijkt altijd af van het ideaal.

Daarom hanteer ik geen harde regels, maar principes.
Ik probeer me eraan te houden, maar soms moet ik afwijken.
Daarna probeer ik er weer naartoe te bewegen.

Alles moet objectief en automatisch testbaar zijn

In het eerste voorbeeld was dat lastig door de complexiteit.
Nu kun je in zilver zeggen: dit aantal moet X zijn.
De measure hoeft alleen nog hetzelfde X te tonen.

Een measure is een contract met de gebruiker

Door de expliciete naam Total Gross Quantity
is meteen duidelijk wat je kunt verwachten.
De definitie is eenvoudig terug te vinden.
Iedereen weet precies wat dat getal betekent.

Kleine wijzigingen + overleg = review

Dit was uiteindelijk een grote wijziging,
gecamoufleerd als een kleine.
Omdat één ontwikkelaar alles in de measure deed,
werd die te zwaar.

Een kort overleg had vragen kunnen oproepen als:
Waarom doe je alles in de measure?

Constante flow van kleine wijzigingen

Door de ontwerpaanpassing zie je dat
de wijziging in zilver en het maken van de measure
losse, kleine stappen zijn.
Die kun je continu doorvoeren
zonder te wachten op een grote release.

Stabiliteit in ontwerp én groei

Zodra definities in zilver vastliggen,
ontstaat een stabiele ondergrond.
Daarop kun je meerdere rapportages bouwen
die sales vanuit verschillende hoeken belichten.

Omdat het fundament staat, kun je snel doorontwikkelen.

Eén onderdeel mag niet te complex worden

en moet over drie maanden nog begrijpelijk zijn

Omdat elk blok code één verantwoordelijkheid heeft,
blijft de complexiteit behapbaar.

Dat maakt het ook begrijpelijk voor nieuwe collega’s
of mensen zonder programmeerachtergrond.

Documenteer daarom altijd waarom iets bestaat.
Niet de programmeertaal, maar de reden. Bijvoorbeeld:

We sluiten ordertype 5 uit omdat dit na 2024
alleen nog wordt gebruikt voor kassakorting.

Met zulke principes bouw je een vuurtoren.
Die geeft richting aan iedereen die meewerkt.
Ook als je tijdelijk moet afwijken door omstandigheden.