Papers we love: Design patterns: hoe kunnen we een gemaakte keuze evalueren?

 
15 januari 2017

Design patterns. Iedereen kent het boek en heeft een aantal (favoriete) patterns in zijn of haar  gereedschapskist om toe te passen wanneer nodig. Maar waar wordt de keuze voor een specifiek pattern eigenlijk op gebaseerd? Niet alleen door Gamma et al, maar in bijna iedere verzameling van patterns wordt een stukje context gegeven die kan helpen een keuze te maken. De context is veelal in de vorm “als het lijkt op X, doe dan Y”.

De realiteit leert ons echter dat we soms een keuze moeten maken tussen een aantal verschillende kanshebbers, elk met eigen voor en tegens. Het maken van zo’n keuze is lastig en wordt ook niet snel geëvalueerd. Dit is lastig, kost veel tijd en het maken van een objectieve vergelijking is erg lastig.

Dit laatste is exact hetgeen er in A Case of Visitor versus Interpreter Pattern  wordt behandeld. Als context wordt er gekozen voor Rascal, een meta-programming language. Om precies te zijn gaat het in het gegeven voorbeeld om een uitting van het Expression Problem[1,2] wat twee opties voor patterns oplevert: het Visitor en het Interpreter pattern.

Centraal in een Visitor pattern is het lostrekken van een specifiek algoritme van de bijbehorende datastructuur waardoor je in staat bent nieuwe algoritmes toe te voegen zonder de bestaande data-elementen of algoritmes aan te passen. Dit wordt gedaan door iedereen een visit method te laten implementeren en per strategie een visitor door middel van double dispatch de juiste method te laten kiezen. Het toevoegen van operaties is hier dan ook erg eenvoudig, elementen is lastiger.

Voor het Interpreter pattern geldt dat je een interpret method toevoegt aan je data-elementen, die zichzelf (en onderliggende elementen) interpreteren aan de hand van een meegegeven context. Hierdoor kan je dus gemakkelijk elementen toevoegen, maar zijn operaties juist weer complexer. Een inhoudelijke bespreking van de patterns is out of scope, maar via de referenties [0,5,6,7,8] is hier genoeg over te vinden.

Door de genoemde tradeoff waren de auteurs echter benieuwd: wat is het beste pattern voor onze usecase? Er was een sterke wens voor zoveel mogelijk statische analyse, door type checking toe te passen encompile errors te geven bij incomplete of foutieve implementaties van het patroon. De codebase is daarnaast aan de start van de paper gebaseerd op het visitor pattern, waardoor er een transformatie naarinterpreter plaats dient te vinden. Deze is geautomatiseerd, waardoor deze herhaalbaar, geautomatiseerd en gelokaliseerd is.

Om uit te kunnen drukken wat “beter” is, zal bepaald moeten worden hoe metingen plaats moeten vinden. Uit het werkveld blijken veel metrieken gefocust op een geaggregeerd beeld. Nu is dit voor management natuurlijk leuk, maar een engineer heeft daar in deze context niets aan. Nadat enkele andere randvoorwaarden de revue passeren wordt uiteindelijk gekozen voor een eigen comparative model. Hierbij wordt niet alleen het onderhoudsscenario, maar ook de analyse van de codebase meegenomen in de beoordeling.

De manier waarop dit is gedaan vind ik even origineel als briljant: druk je gehele model, van analyse tot onderhoudsscenario uit in een DSL, zodat je semi-geformaliseerde “maintenance programs” krijgt. Iedere atomaire actie binnen een maintenance program geef je een gewicht en de relatieve complexiteit van een “programma” is de som hiervan. Door de verschillende programma’s met elkaar te vergelijke krijg je een aardig beeld over welk scenario nu het best opgelost wordt met een interpreter of juist met een visitor pattern.

In de paper worden negen onderhoudsscenarios beschreven, variërend van bugfixing tot het toevoegen van nieuwe features. Aan het eind worden deze op een rijtje gezet en met elkaar vergeleken. Zoals altijd komt hier weer een genuanceerde conclusie uit: beide patterns hebben voor-, en nadelen.

De kracht zit hem in mijn ogen echter niet in de conclusie van de paper, maar in de manier waarop dit onderzoek is uitgevoerd. Er een heel duidelijk model neergezet om een dergelijke vergelijking uit te voeren. Dit model is echter verre van standaard en is heel duidelijk ontstaan door pragmatisch met de probleemstelling om te gaan. Het is jammer dat er niet wordt ingegaan op dit proces, maar ik kan me goed indenken dat dit een aantal leuke “aha-erlebnis” momenten gehad heeft.

De les zit wat mij betreft ook in het doorlopen proces. Vanaf de onderzoeksopzet tot de conclusies: er wordt continu kritisch naar de uitgangspunten gekeken en men blijft heel expliciet open staan voor de uitkomsten. Ook als deze verrassend zijn, maar geen grote impact hebben blijf je dit terug zien. Dit in combinatie met de pragmatische houding en de goede leesbaarheid maakt het wat mij betreft erg leuk om te lezen. Kortom, een aanrader!


Over deze papers we love: binnen Sogyo hebben we de traditie dat we maandelijks een nieuwsbrief rondsturen. De nieuwsbrief gaat veel over interne feitjes, echter sinds februari 2015 verzorgd Kevin van der Vlist het topic: papers we love. Hij deelt met ons papers die interessant zijn om te lezen en ons kunnen inspireren. De topic is uitgegroeid tot een mooie verzameling die we ook graag hier willen delen.


Werken met ?
Kijk dan bij onze mogelijkheden voor zowel starters als ervaren engineers.


Categorieën: Gave Technologie