Een case voor de usecase

In de context van agile development wordt voor de specificatie van functionaliteit vaak rechtstreeks gegrepen naar user stories, waardoor een agile team vaak binnen zeer korte tijd aankijkt tegen een enorme stapel van user stories, die stuk voor stuk een promise for a future conversation inhouden. Moeten we dan niet die gesprekken maar eens gaan voeren? Wat doen we met de uitkomst van die gesprekken? Hoe voorkomen we dat we dezelfde gesprekken steeds weer opnieuw gaan voeren? Vanuit die gedachtegang werpen Jim Coplien en Gertrud Bjørnvig, in hun boek Lean Architecture for Agile Software Development, een case op voor de usecase.

Usecases beschrijven wat het systeem voor de gebruikers doet, c.q. wat gebruikers met het systeem doen. Het voornaamste doel is dat je op een hanteerbare manier vastgelegd krijgt wat je met alle betrokken sleutelfiguren hebt besproken over de functionaliteit en welke beslissingen daarover zijn genomen, zodat je een basis hebt om het systeem mee op te bouwen en te testen, maar ook om het systeem mee te onderhouden/aan te passen/uit te breiden.

Een usecase gaat over een doel dat een gebruiker met het systeem wil bereiken. Om te beginnen is daarom inzicht nodig in de verschillende soorten gebruikers van het systeem. Leg voor elk type gebruiker een naam en een eenduidige omschrijving vast waar alle stakeholders zich in hebben kunnen vinden.

Naast de namen en omschrijvingen van de gebruikers is het ook goed om een treffende naam voor het systeem te kiezen en liefst ook een korte, maar heldere probleemdefinitie. De probleemdefinitie geeft heel expliciet aan wat het gat is tussen de huidige situatie en de gewenste situatie, dat het systeem moet gaan opvullen. Zo’n uitgeschreven en zichtbaar gedeelde probleemdefinitie geeft steeds veel focus voor alle betrokkenen.

Vanuit deze context (systeemnaam, probleemdefinitie, naam en omschrijving per gebruikerstype) kan je snel tot een helicopterview van het systeem komen, door voor elke type gebruiker z’n voornaamste doelen op te sommen. De genoemde doelen vormen dan de namen van usecases, want een usecase gaan over een doel dat een gebruiker met het systeem wil bereiken.

Bijvoorbeeld in het geval van de Groenland Bank, een nieuw onlinesysteem voor een fictieve bank, zou een eerste helicopterview er zo uit kunnen zien:

Rekeninghouder
Recente transacties bekijken
Geld overschrijven
Rekeningafschriften afdrukken
Terugkerende betaling toevoegen
Nota betalen

Niet alleen in dit voorbeeld, maar ook in de werkelijke praktijk is het nadrukkelijk de bedoeling om de helicopterview simpel en compact te houden. Het aantal doelen per gebruiker blijft ook bij complexe systemen beperkt, omdat de complexiteit niet zozeer zit in het aantal usecases, maar in de variatie binnen de verschillende usecases. Per usecase beschrijven we namelijk om te beginnen als basis een mooiweerscenario dat later wordt aangevuld met losstaande beschrijvingen van anomalieënafwijkingen van het mooiweerscenario. Het systeem wordt complexer naarmate er meer anomalieën geïmplementeerd worden.

Voordat het mooiweerscenario wordt uitgewerkt, leggen we van een nieuwe usecase eerst de volgende zaken vast (zoals ze met alle sleutelfiguren samen besproken zijn):

  • Businessmotivatie
  • Gebruikersintentie
  • Preconditie
  • Postconditie

Bijvoorbeeld voor de Geld overschrijven usecase van de Groenland Bank:

Businessmotivatie
Als onderdeel van onze strategie Stel de klant in staat z’n bankzaken thuis te regelen zien we het overschrijven van geld als een belangrijke dienst. De Rekeninghouder kan z’n rekeningen in de gaten houden en geld overschrijven naar een rekening waar het saldo te laag van wordt of waarvan de Rekeninghouder dat binnenkort verwacht. Het kan ons (de bank) de tijd besparen om brieven te sturen over te lage saldo’s en het kan ook voorkómen dat we rekeningen moeten sluiten en ze later weer heropenen. Als aanvulling zouden we ook graag zien dat de Rekeninghouder geld kan overschrijven naar rekeningen van andere Rekeninghouders – zowel binnen onze eigen bank als van en naar andere banken. Onze concurrenten bieden die diensten al aan en we kunnen daar zelf niet veel langer mee wachten.
Gebruikersintentie
Als Rekeninghouder wil ik geld kunnen overschrijven tussen mijn rekeningen, zodat ik ervoor kan zorgen dat ik nergens roodsta en mijn betaalpas wordt geblokkeerd.
Preconditie
De Rekeninghouder is ingelogd bij de Groenland Bank en een overzicht van z’n rekeningen wordt getoond op het scherm.
Postconditie
Het bedrag dat de Rekeninghouder heeft ingevoerd is verplaatst van de bronrekening naar de bestemmingsrekening. De twee rekeningen zijn in balans en de transactielogs zijn bijgewerkt.

Het mooiweerscenario wordt nu als volgt beschreven:

  • In een tabel met kolommen voor Stapnummers, voor de Gebruikersintentie, voor de Systeemverantwoordelijkheid, en voor Commentaar.
  • Elke stapbeschrijving begint met de gebruikersnaam/de systeemnaam.
  • De gebruikte terminologie is weloverwogen gekozen en wordt consistent toegepast. Het is aan te bevelen om een begrippenlijst bij te houden waarin de gebruikte termen worden gedefinieerd. Deze begrippen vormen feitelijk bouwstenen voor de architectuur van het systeem.
  • Eventuele toelichtingen, besluiten, open discussiepunten en nieuwe vragen worden genoteerd in de kolom Commentaar.

Bijvoorbeeld weer voor de Geld overschrijven usecase van de Groenland Bank zou het mooiweerscenario er als volgt uit kunnen zien:

Stap Gebruikersintentie Systeemverantwoordelijkheid Commentaar
1 De Rekeninghouder selecteert een bronrekening en kiest voor Overschrijven. De Groenland Bank toont de bronrekening, een lijst van bestemmingsrekeningen en een veld om het bedrag in te voeren. Moet de Rekeninghouder eerst voor Overschrijven kiezen en dan de bestemmingsrekening, of omgekeerd?

De lijst van bestemmingsrekeningen is standaard: de eigen rekeningen van de Rekeninghouder, met uitzondering van de bronrekening

2 De Rekeninghouder kiest een bestemmingsrekening, voert het bedrag in en accordeert. De Groenland Bank toont de overschrijvingsgegevens (bronrekening, bestemmingsrekening, datum, bedrag) en vraagt een wachtwoord om de overschrijving te bekrachtigen. De standaarddatum is de huidige datum.
3 De Rekeninghouder voert het wachtwoord in en accordeert de overschrijving. De Groenland Bank verplaatst geld, werkt de boeken bij en toont een transactiebewijs. Routine: Geld verplaatsen en boeken bijwerken.

Is transactiebewijs de juiste term?

Is een transactiebewijs wel nodig als de transactie tussen twee eigen rekeningen is?

Moet de Rekeninghouder het transactiebewijs kunnen printen?

In stap 3 wordt verwezen naar een routine; dat is een opeenvolging van systeemacties, die in verschillende usecases op dezelfde manier gebruikt kan worden. Voor een routine worden geen businessmotivatie of gebruikersintentie beschreven, want die volgen uit de betreffende usecase (en die verschillen dus ook voor de verschillende usecases die de routine gebruiken). Routines kennen ook geen anomalieën; het zijn eenduidige stukjes lopendebandwerk. Van elke routine worden vastgelegd:

  • Naam
  • Preconditie
  • Stappen
  • Postconditie

De definitie van de routine Geld verplaatsen en boeken bijwerken in de Groenland Bank is bijvoorbeeld als volgt:

Preconditie
Een geldige bronrekening en bestemmingsrekening zijn bekend, evenals het bedrag dat moet worden overgeschreven.
Stappen
  1. Groenland Bank verifieert voldoende saldo;
  2. Groenland Bank werkt de rekeningen bij;
  3. Groenland Bank werkt de gegevens voor de rekeningafschriften bij.
Postconditie
De periodieke rekeningafschriften geven de precieze aard van de transactie weer (een overschrijving is een overschrijving – niet een combinatie van een opname en een storting)

Zoals gezegd zullen in verdere discussies over de usecase allerlei afwijkingen van het mooiweerscenario naar boven komen – de anomalieën. Het aardige is nu dat je in de beschrijving van elke anomalie kan verwijzen naar een specifieke stap in het mooiweerscenario.

De lijst van anomalieën binnen de Geld overschrijven usecase van de Groenland Bank zou er op een bepaald moment bijvoorbeeld als volgt uit kunnen zien:

Stap Ref Afsplitsende actie Commentaar
1a De Rekeninghouder voegt een tekst toe aan de transactie op de bronrekening. Hoort dit niet in het mooiweerscenario?

Wat is de standaardtekst als de Rekeninghouder geen tekst toevoegt?

1b De Rekeninghouder wil overschrijven naar een rekening van een andere klant. De Rekeninghouder moet de naam en het rekeningnummer invoeren.
1c De Rekeninghouder wil een andere rekening van de Rekeninghouder toevoegen aan de bestemmingenlijst. De Rekeninghouder kan de rekening een naam geven (verplicht?)
2a Er staat niet genoeg geld op de bronrekening om de overschrijving te doen. Toon een foutmelding en draai de transactie terug. (Wie gaat er over meldingen aan de Rekeninghouder? Definieer minimaal saldo?)
2b De Rekeninghouder voegt een tekst toe aan de transactie op de bestemmingsrekening. Hoort dit niet in het mooiweerscenario?

Wat is de standaardtekst als de Rekeninghouder geen tekst toevoegt?

2c Het bedrag voldoet niet aan de validatieregels. Validatieregels?
2d De Rekeninghouder voert een toekomstige datum in voor de overschrijving. De Groenland Bank biedt de mogelijkheid om een toekomstige datum in te voeren. De overschrijving zal plaatsvinden op die dag, volgens bankdagen. (Hoe ver in de toekomst mag de datum liggen?)
3a Incorrect wachtwoord. Blokkeren?
3b De transactie is langer bezig dan de maximaal geoorloofde tijdsduur. Mogelijke oorzaken voor langere tijd? Welke acties als dit gebeurt? Wat is de maximaal geoorloofde tijdsduur?
3c De transactie faalt Mogelijke oorzaken voor falen? Welke herstelacties? Toepasselijke meldingsteksten?
Alle De Rekeninghouder zoekt online hulp. Wie is verantwoordelijk voor online hulp?

Wanneer tijdens discussie over een usecase een anomalie boven komt drijven, is het aan te bevelen om die meteen te noteren, zodat die discussie later niet opnieuw gevoerd hoeft te worden. Niet alle beschreven anomalieën moeten per se geïmplementeerd worden – per release bepaal je welke mooiweerscenario’s van nieuwe usecases en welke anomalieën van bestaande usecases je wil toevoegen (dit is een businessbeslissing). Van elke usecase is het mooiweerscenario het eerste dat wordt geïmplementeerd, als basis voor verdere uitbreidingen. Een enkele anomalie zal in de eerste release al meteen meekomen, andere volgen in latere releases, sommige blijven steeds weer op de plank liggen, terwijl ondertussen alweer nieuwe gevallen worden toegevoegd – het aantal anomalieën per usecase is in principe onbegrensd.

Met het stabiele mooiweerscenario en de variatie in de anomalieën, focus je met de usecase de verdere discussie steeds richting geïnformeerde, weloverwogen beslissingen over altijd weer nieuwe functies en features, uitbreidingen, uitzonderingen, alternatieven, foutafhandeling en nonfunctional requirements.

Web design? Resilient?

In the early days of the world wide web, determining the layout and function of a web page on a screen was approached pretty much the same as in the case of  a page in “print”. Which is actually quite understandable, since designers tend to design with designers’ minds, using designers’ tools. Try Photoshop: when starting a new document, the first thing to do is to set its width and height. The fixed-width approach to web page design, though crippled form the start, only started to grow really problematic since the appearance of the iPhone, and later the iPad, and the myriad of alternatives – all similar, but all with very distinctive screen widths. The problem was, as Jeremy Keith very eloquently points out in his amiable (and free!) book Resilient web design, that using fixed-width elements to design a web page rendered on variable-width screens, is materially dishonest.

But now we know better. Right? Now we use HTML strictly for marking up the meaning of content, and CSS strictly for presentation. That’s materially honest. And it’s a nice separation of concernsSo we use a table element to mark up the structure of tabular data, and never for layout purposes. Right? In HTML5, we even explicitly obsoleted the align and width attributes on table elements. Good for us!

The pair of HTML + CSS are very pleasantly loosely coupled: while the HTML would contain some hooks for the CSS to cling to, exactly the same HTML content can be presented in any imaginable way by applying changes to just the CSS, while on the other hand one single CSS file can serve to style any thinkable content in HTML. Another remarkable property is that the same HTML, when for whatever reason the accompanying CSS  is crippled or lost, will still get presented in a perfectly readable way. In a not so beautiful, default way, but still entirely useful for a clear interpretation of the content at hand.

But there’s more.

Both HTML and CSS share the property of being a declarative languagemeaning they don’t instruct a computer to follow a step-by-step recipe, but just define some information (HTML: meaning, CSS: presentation) about some content. This renders them a very forgiving attitude to errors: when a browser is rendering a page, and encounters an HTML tag it doesn’t recognise, it ignores the markup, and displays the tag’s content. It doesn’t report an error, it doesn’t stop processing, it just does the default thing, keeps calm, and carries on. Same thing in CSS: unknown selectors, properties, and values are just ignored, a default style is applied, and processing continues. That behaviour is by design, and it’s tremendously powerful! It’s a huge advantage. It really is. It’s true.

Thing is, the liberal way in which HTML & CSS are parsed, enables a profoundly robust route for innovation by leveraging the ever-extending feature sets of modern web browsers. Not every user on the web has the latest and greatest browser version installed, and not every device has the topmost capabilities. Still, it’s perfectly safe to use the hottest of the new stuff in your HTML and CSS, since you can rely on any non-supporting browser to just keep calm, and carry on. Nothing will break; some get to see the full glory of your endless creativity, everyone will get the same content in one perfectly usable presentation or another. Websites don’t need to look exactly the same in every browser.

Of course we have to consider that other language of the web as well: JavaScript. It’s quite popular. JavaScript is used in many ways, but its main concern is enabling advanced interactions between the content and the user, and between different elements within the content. A major difference with HTML & CSS is that JavaScript is an imperative language, instead of a declarative one. It defines a step-by-step program that the browser should execute. If something fails, an error is thrown, and execution stops. Compared to HTML & CSS, JavaScript is very, very breakable. It enables many nice ways of interaction, but it’s safest to look at those more as enhancements, than as core functionality. There’s a lot of things that can go wrong – it’s safe and wise to use it, but you’d better not rely on it for any core functionality.

Then what is a sound approach? Three steps:

  1. Identify core functionality.
  2. Make that functionality available using the simplest possible technology.
  3. Enhance!

That’s the strategy for what’s known as progressive enhancementIt enables you to go as wild as you want on the latest and greatest hot new stuff, because you can always rely on the safety net of your basic resilient HTML+CSS design. Thoughtfully starting off with full focus on the basics, using the plain old bare open standards of the web isn’t actually setting you back to what we regarded normal in the days of Geocities – quite the contrary: it’s a great enabler of experiment and innovation. All by design. Enhancing progressively is an act of future friendliness.

If you follow the buzz, it very much seems that web development is just another word for choosing one of the popular JavaScript frameworks. The case for progressive enhancement in Resilient web design quite firmly augments to the reasons why e.g. React is a terrible idea (it’s sad!) It also adds to a solid foundation for the powerful recommendations of ROCA – resource oriented client architecture.

Enfin, you might want the book as well. It’s a good read.