State of shock (1)

In dit artikel wil ik ingaan op verandering van gedrag. Hetzelfde object gedraagt zich andersin een specifieke situatie of als het ergens door getriggerd wordt. Daarvoor heb je het State Design Pattern en de State Machine.

Wat

Het State Design Pattern biedt een manier om het gedrag van een object te veranderen. Je hebt dus het zelfde object met dezelfde methods, maar deze geven een ander resultaat als de situatie verandert.

Waarom

Wanneer al je alle logica is gevangen in één blok code vol switch statements of if-then condities, is het niet te lezen door een collega, en ook niet testbaar. Deze soms ‘geniale’ code is een black box: het werkt zoals het moet – maar die niemand snapt waarom en niemand durft het meer aan te passen. Het is daarom slechte code: Goede code moet je kunnen lezen en meteen kunnen doorzien. En het moet testbaar zijn.

Het Design Pattern draagt hier aan bij. Je isoleert per situatie het gedrag, dus wat moet een method per situatie doen. Hierdoor kan je ook een code voor nieuwe situatie toevoegen, zonder het gedrag van de andere situaties te beïnvloeden.

Hoe

knikkerbaan

Volg de bal: Het debuggen en tracen van Geniale code 

Bij slechte code stop je alle logica in het object, zodat je constant if-then of switch moet gebruiken om in iedere situatie aan de business-rules te voldoen.

Met het State Design Pattern kijk je eerst naar de mogelijke situaties of context waarin een object kan verkeren. Ook maak je een lijst van alle gedragingen die daardoor worden beïnvloed; dit zet je een interface met alle methods en properties. Vervolgens maak je op basis van deze interface voor iedere context een eigen class. Op deze manier  groepeer en isoleer je alle logica voor per context.

Vervolgens zorg je ervoor dat het object al zijn mogelijke situaties kent. Maar als je het object gebruikt, bepaal je eerst in welke context deze is en welke class moet worden gebruikt. Vervolgens kan het object zijn werk doen dat bij die situatie hoort.

Concreet

Stel dat je een site hebt waarbij bezoekers zich kunnen inschrijven bij een voetbalteam in een pool. De bezoeker (= het object) heeft daarmee de rol als teamlid (= de context). Maar een team heeft ook een aanvoerder nodig. De inschrijving van één van de teamleden moet dan worden aangepast naar de rol van teamleader. Het is dezelfde persoon, maar hij is in zjin nieuwe rol verantwoordelijk voor het beheer van het team, dus zijn gedrag verandert.

Bij het programmeren kan je dit oplossen door overal “als persoon teamleader is, doe dan X anders doe Y” in te bouwen. Maar dan loop je vast als de site eigenaar ook nog een poolcoördinator wil toevoegen, want voetballen doe je in een pool en je hebt iemand nodig die onpartijdig is en alle teams binnen een pool kan beheren.

We moeten dus het gedrag in kaart brengen wat leden mogen doen. Dit omschrijven we in een interface, in ons geval zouden dat de volgende methods en properties kunnen zijn:

  • ToonSpeelschema(pool)
  • VeldPositie [keeper, verdediger, middenveld, spits]
  • MijnTshirtMaat [s,m,l,xl]
  • ToonMijnTeamLeden(teamnummer)
  • GegevensWijzigenTeamlid(teamlid)
  • VerwijderTeamlid(teamlid)

We hebben nu drie types lidmaatschap: het teamlid, de teamleader en de poolcoördinator. Voor ieder type maak je op basis van het interface een eigen class met de eigen logica. Omdat je een interface gebruikt moet je iedere method en property implementeren, ook als deze niet relevant is voor een type lidmaatschap.

Zo kan je businessrules per situatie implementeren. Een teamleader mag ‘VerwijderTeamlid’ aanroepen om mensen uit het team te gooien, dat mag een teamlid niet doen. En omdat een poolcoördinator niet meespeelt op het veld zal hij geen Veldpositie hebben en geen deel uitmaken van een team, dus kan hij niet ‘ToonMijnTeamLeden’ uitvoeren. In dat geval doet de method niets of geeft deze null of een (fout)melding terug.

Door alle classes op de interface te baseren zijn alle methods aanwezig voor iedere context en kan je per situatie bepalen welke implementatie je gebruikt.

In het volgende artikel wil ik meer ingaan op de State machine.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s