Copy, paste, adjust, repeat, copy, paste adjust, repeat. Op de dansvloer beter bekend als eat, sleep, rave, repeat van Fatboy Slim. Bij MetaFactory mag er graag wat house, of techno door het kantoor galmen aan het eind van de middag. Wij hebben dan ook een speciale relatie met copy, paste, adjust, repeat. Bij MetaFactory voorkomen we namelijk dit gedrag tijdens het programmeren. We luisteren liever naar Fatboy Slim.
Waarom zijn patronen in software goed?
Als je een software systeem maakt, of een aantal systemen, dan wil je dat er patronen in die software zitten.
Patronen zijn goed voor gebruikers van software. Gebruikersinterfaces moeten vergelijkbare functionaliteit hebben. Als je bijvoorbeeld vanuit een lijst een Excel kan genereren, dan verwacht de gebruiker dat je dat bij andere lijsten ook kan doen. Interfaces moeten vergelijkbare ontwerpen hebben. Als de ‘toevoegen nieuw’ knop bij de een lijst rechtsboven zit, dan verwacht de gebruiker die bij andere lijsten ook rechtsboven. Systemen moeten een vergelijkbare workflow kennen. Als je bij het verwijderen van een record een ‘weet u het zeker’ dialoog ziet, dan verwacht de gebruiker die ook bij andere verwijder-functionaliteiten.
Ook voor ontwikkelaars is het goed om patronen in software te hebben. Je wilt dat naamgeving consistent is opgebouwd. Je wilt dat vergelijkbare functies op een vergelijkbare manier zijn geïmplementeerd. Als je als ontwikkelaar later aan een project wordt toegevoegd, of onderhoud gaat doen op een bestaand systeem, dan helpen consistente oplossingen je in het sneller eigen worden van het systeem. Een deel van het systeem leert je dan namelijk ook veel over het gehele systeem. Als je 1 rest-controller kent, dan hoop je ze allemaal te kennen. Uiteraard is er specifieke business logica die uniek is. En dat is precies waar je je als ontwikkelaar op wilt concentreren. Voor de overige software wil je geen varianten, persoonlijke smaken en voortschrijdend inzicht tegenkomen.
‘Maar onze software heeft geen patronen’
‘Maar onze software heeft geen patronen’, is een vaak gehoorde opmerking van ontwikkelaars die voor het eerst met MetaFactory in aanraking komen. Die uitdaging gaan we als MetaFactory graag aan. Toon ons je software en wij tonen jou de patronen erin. Je kunt niet alles oplossen met generics, overerving of functioneel programmeren. Als je abstract naar je broncode kijkt, dan ga je op verschillende lagen van je software patronen herkennen. MetaFactory kan je helpen ze te leren herkennen.
Copy, paste, adjust, repeat, copy, paste, adjust, repeat
Hoe gaat het programmeren nu vaak? De ambachtelijke wijze, zoals wij dat bij MetaFactory noemen. Je programmeert een functie, laat hem testen en levert hem op aan de gebruiker. De gebruiker is tevreden en jij bent trots op een puik stukje software. Nu komt de gebruiker met een vergelijkbare vraag. Je kopieert de broncode, past de code aan om het geschikt te maken voor de nieuwe functie, laat hem testen en levert hem op aan de gebruiker. En weer is iedereen blij. Maar nu heb je bij het kopiëren een fout geïntroduceerd die er bij het testen en het gebruik niet direct uitkomt. Ook Sonarqube attendeert jou daar niet op. En nog een gebruikerswens. En weer kopiëren – inclusief de bug –, aanpassen, testen en opleveren. En weer een nieuwe wens. Je kopieert de laatste versie inclusief de bug. Bij deze inmiddels 4e implementatie heb je naar aanleiding van een goed artikel op Stack Overflow ontdekt dat de oplossing nog eleganter kan. Je implementeert deze oplossing in je laatste functie. Samenvattend heb je nu:
- Functie 1: de originele versie
- Functie 2: een aangepaste kopie van functie 1, inclusief bug
- Functie 3: een aangepaste kopie van functie 2, inclusief bug
- Functie 4: een aangepaste kopie van functie 3, inclusief bug en een verbeterde implementatie
Functie 1, 2, 3 en 4 vormen samen een patroon. De ambachtelijke handeling is die van copy, paste, adjust, repeat.
Helaas is er geen tijd om de verbeterde implementatie bij functie 4 te implementeren bij functie 1,2 en 3. Ze werken immers en de gebruikers willen nieuwe functionaliteit.
Nu wordt de bug ontdekt in functie 3. De bug wordt gefixed en je komt erachter dat de bug ook in functie 2 voorkomt. Voor de zekerheid ook maar functie 1 en functie 4 nalopen. In functie 1 was deze bug gelukkig niet aanwezig. Bij functie 4 zat de bug ook, maar het was best nog even zoeken door de verbeterde implementatie.
Tenslotte wil de gebruiker nieuwe functionaliteit op alle 4 de functies. Je past functie 1, 2, 3 en 4 stuk voor stuk aan. De functies worden 1 voor 1 getest en in productie genomen.
Hoe werkt het met de Code Composer?
MetaFactory vindt dat dit ambachtelijke programmeren beter kan. MetaFactory wil dat jouw voortschrijdende inzicht opgedaan in functie 4 ook in functie 1, 2 en 3 geïmplementeerd moet worden. Zonder dat dit ten koste gaat van het budget van de gebruiker die extra functionaliteit wil in plaats van technisch onderhoud. MetaFactory wil dat de bug gesignaleerd in 1 van de functies direct wordt opgelost in alle vergelijkbare functies.
Met de Code Composer van MetaFactory gaat data anders. Functie 1 bouw je, net als hierboven geschreven met de hand. Je laat ook deze functie testen en gebruiken. Vervolgens vertaal je de handgeschreven broncode naar zogenaamde ‘code instructies’ en een (data)’model’ van je eerste functie. We hebben tools die je daarbij ondersteunen. Dan laat je de Code Composer de broncode genereren op basis van de code instructies en je model van functie 1. Als de door MetaFactory gegenereerde broncode hetzelfde is als je handgeschreven code, dan is deze stap geslaagd. Vervolgens breidt je het model uit voor functie 2, 3 en 4. MetaFactory genereert vervolgens op basis van de modelbeschrijving van functie 1, 2, 3 en 4 en de code instructies de broncode voor functie 1,2, 3, en 4. Je voorkomt hiermee dat je dus een bug introduceert bij het kopiëren en aanpassen, zoals in het ambachtelijke voorbeeld hierboven wel gebeurde. En als je de op Stack Overflow gevonden elegante oplossing wilt implementeren, dan pas je de code instructies aan. Jouw elegante oplossing is na genereren beschikbaar in functie 1,2,3 en 4. En als de gebruiker de extra functionaliteit geïmplementeerd wil zien, dan voeg je deze toe aan de code instructies en genereert opnieuw de broncode voor functie 1, 2, 3 en 4.
Dus: al jouw broncode is altijd conform jouw meest recente inzichten, de kwaliteit van je code neemt toe en je productiviteit neemt toe. Zitten er geen addertjes onder het gras? Jazeker: als je de bug namelijk al bij je eerste functie introduceerde, dan zit deze bug na het genereren ook in functie 2,3 en 4. Maar goed, dat had je in de handmatige, ambachtelijke situatie ook gehad. En als je de bug verwijdert uit je code instructies, dan is hij er in alle functies ook direct uit.
Middels metadata en hooks zijn allemaal mogelijkheden in MetaFactory ingebouwd om bijvoorbeeld functie 2 net iets anders te laten werken dan functie 1, 3 en 4. Je kan dus altijd nog precies de broncode zo maken als je zelf wilt en blijven genereren.
Wanneer moet je MetaFactory gaan gebruiken?
Wij bij MetaFactory kunnen ons voorstellen dat het best lastig is om patronen te herkennen in je software. Maar als je bij je zelf merkt dat je aan het copy, paste, adjust, repeaten bent, dan moet je aan ons denken. Wij helpen je dan graag. Kan jij je weer richten op de business logica en houd je tijd over om ’s-avonds uit te gaan. Eat, sleep, rave, repeat. Of eat, sleep, code, repeat, dat kan natuurlijk ook. Dat snappen we bij MetaFactory. Programmeurs hebben gewoon het mooiste beroep van de wereld.
Interesse? Neem nu contact met ons op.