Ga niet akkoord met het ontwikkelen van dingen die je niet begrijpt

Ga niet akkoord met het ontwikkelen van dingen die je niet begrijpt

Sinds begin 2018 ben ik leidinggevende / hoofdontwikkelaar in het team - noem het zoals je wilt, maar het komt erop neer dat ik volledig verantwoordelijk ben voor een van de modules en voor alle ontwikkelaars die eraan werken. Deze positie geeft me een nieuw perspectief op het ontwikkelingsproces, omdat ik betrokken ben bij meer projecten en actiever deelneem aan beslissingen. Onlangs, door deze twee omstandigheden, realiseerde ik me onverwachts hoezeer begrip invloed heeft op de code en de applicatie.

De boodschap die ik wil overbrengen, is dat de kwaliteit van de code (en het eindproduct) nauw verbonden is met het niveau van begrip van de mensen die ontwerpen en code schrijven.

Misschien denk je nu: "Dank je wel, kapitein. Natuurlijk is het goed om te begrijpen wat je schrijft. Anders kun je net zo goed een groep apen inhuren om willekeurig op toetsen te slaan, en daarmee klaar zijn." En je hebt volkomen gelijk. Daarom neem ik als vanzelfsprekend aan dat je beseft dat je een algemeen begrip moet hebben van wat je doet. Dit kan het nulniveau van begrip worden genoemd, en daar gaan we niet in detail op in. We zullen in detail bespreken wat je precies moet begrijpen en hoe dit invloed heeft op de beslissingen die je elke dag neemt. Als ik deze dingen van tevoren had geweten, had ik veel tijd en twijfelachtige code kunnen besparen.

Hoewel je hieronder geen ene regel code zult zien, geloof ik toch dat alles wat hier is gezegd van groot belang is voor het schrijven van kwalitatieve, expressieve code.

Eerste niveau van begrip: Waarom werkt het niet?

Ontwikkelaars komen meestal op dit niveau in de vroegste fasen van hun carriĆØre, soms zelfs zonder enige hulp van anderen — althans, dat is wat ik heb waargenomen. Stel je voor dat je een bugrapport ontvangt: een bepaalde functie in de applicatie werkt niet, deze moet worden gerepareerd. Wat ga je doen?

Het standaardproces ziet er als volgt uit:

  1. Zoek de specifieke code die het probleem veroorzaakt (hoe je dat doet, is een apart onderwerp; dit behandel ik in mijn boek over verouderde code)
  2. Breng wijzigingen aan in dit fragment
  3. Zorg ervoor dat de bug is opgelost en er geen regressiefouten zijn opgetreden

Laten we nu focussen op het tweede punt: het aanbrengen van wijzigingen in de code. Er zijn twee benaderingen voor dit proces. De eerste: begrijp wat er precies gebeurt in de huidige code, identificeer de fout en corrigeer deze. De tweede: werk op gevoel — voeg bijvoorbeeld +1 toe in de voorwaardelijke instructie of loop, kijk of deze functie nu werkt in het gewenste scenario, probeer dan nog iets en ga zo eindeloos door.

De juiste benadering is de eerste. Zoals Steve McConnell uitlegt in zijn boek Code Complete (waarvan ik trouwens een sterke aanbeveling doe), moeten we elke keer dat we iets veranderen in de code, in staat zijn om met vertrouwen te voorspellen hoe dit de applicatie zal beĆÆnvloeden. Ik spreek hier uit het hoofd, maar als een bugfix niet werkt zoals je verwachtte, zou dat je alarmeren en moet je je hele actieplan in twijfel trekken.

Samenvattend, om een solide bugfix uit te voeren die de kwaliteit van de code niet verslechtert, moet je zowel de structuur van de code als de oorsprong van het specifieke probleem begrijpen.

Tweede niveau van begrip: Waarom werkt het?

Dit niveau is veel minder intuĆÆtief te begrijpen dan het vorige. Ik, als nog beginnende ontwikkelaar, heb dit geleerd van mijn manager en heb het later zelf vaak uitgelegd aan beginners.

Laten we deze keer aannemen dat je tegelijk twee bugrapporten hebt ontvangen: de eerste betreft scenario A, de tweede scenario B. In beide scenario's is er iets mis. Dus begin je met de eerste bug. Volg de principes die we hebben vastgesteld voor het eerste niveau van begrip, duik de code in die verband houdt met het probleem, ontdek waarom deze de applicatie op deze manier laat functioneren in scenario A, en breng redelijke aanpassingen aan die precies het resultaat geven dat je verwachtte. Alles gaat prima.

Daarna ga je verder met scenario B. Je herhaalt het scenario in een poging de fout uit te lokken, maar — verrassing! — nu werkt alles zoals het hoort. Om je vermoeden te bevestigen annuleer je de wijzigingen die zijn aangebracht tijdens het oplossen van bug A, en bug B komt weer terug. Je bugfix heeft beide problemen opgelost. Wat een geluk!

Je had hier totaal niet op gerekend. Je hebt een manier bedacht om de fout in scenario A te corrigeren en je hebt geen idee waarom het ook voor scenario B werkte. Op dit moment is de verleiding groot om te denken dat beide taken succesvol zijn uitgevoerd. Dat klinkt logisch: het doel was immers om de fouten te verhelpen, nietwaar? Maar het werk is nog niet af: je moet nog uitzoeken waarom jouw acties de fout in scenario B hebben verholpen. Waarom? Omdat het mogelijk is dat dit scenario op onjuiste principes werkt, en dan moet je naar een andere oplossing zoeken. Hier zijn een paar voorbeelden van zulke situaties:

  • aangezien de oplossing niet specifiek is afgestemd op fout B met inachtneming van alle factoren, heb je misschien, zonder het te beseffen, functie C gebroken.
  • Het is mogelijk dat er ergens nog een derde bug schuilgaat die met dezelfde functie te maken heeft, en jouw bugfix zorgt ervoor dat de juiste werking van het systeem in scenario B afhankelijk is van deze bug. Op dit moment lijkt alles goed, maar op een dag zal deze derde bug ontdekt en verholpen worden. Dan verschijnt er weer een fout in scenario B, en hopelijk slechts daar.

Al deze zaken brengen chaos in de code, en zullen je ooit op de kop vallen - hoogstwaarschijnlijk op het slechtst denkbare moment. Je moet je doorzetten om de tijd te nemen om te begrijpen waarom alles ogenschijnlijk werkt, maar het is de moeite waard.

Derde niveau van begrip: Waarom werkt het?

Mijn recente inzicht heeft alles te maken met dit niveau, en waarschijnlijk had dit mij de meeste voordelen gegeven als ik deze gedachte eerder had gehad.

Om het duidelijker te maken, laten we het voorbeeld bekijken: je moet je module compatibel maken met functie X. Je bent niet echt goed bekend met functie X, maar je hebt gehoord dat je het framework F moet gebruiken voor compatibiliteit. Andere modules die integreren met X werken precies met dit framework.

Je code heeft vanaf dag ƩƩn nooit contact gehad met framework F, dus het implementeren ervan zal niet eenvoudig zijn. Dit zal ernstige gevolgen hebben voor sommige onderdelen van de module. Desondanks ben je volledig ondergedompeld in de ontwikkeling: je schrijft wekenlang code, test, lanceert proefversies, ontvangt feedback, corrigeert regressiefouten, ontdekt onvoorziene complicaties, houdt niet aan de oorspronkelijk afgesproken deadlines, schrijft nog meer code, test, ontvangt feedback, corrigeert regressiefouten — dit alles om framework F te implementeren.

Op een bepaald moment besef je ineens — of misschien hoor je het van iemand — dat framework F je misschien helemaal geen compatibiliteit met functie X zal geven. Misschien waren al deze tijd en inspanningen helemaal niet goed besteed.

Iets dergelijks overkwam me ooit tijdens een project waar ik verantwoordelijk voor was. Waarom gebeurde dit? Omdat ik niet goed begreep wat de essentie van functie X was en hoe het zich verhoudt tot framework F. Wat had ik moeten doen? Iemand die de ontwikkelingsopdracht geeft, vragen om op een duidelijke manier uit te leggen hoe het geplande actieplan leidt tot het gewenste resultaat, in plaats van gewoon te herhalen wat voor andere modules is gedaan of blind te geloven dat dit nodig is voor functie X.

De ervaring van dit project leerde me om te weigeren met de ontwikkeling te beginnen totdat we een duidelijk begrip hebben van waarom we gevraagd worden bepaalde acties te ondernemen. Weiger openlijk. Wanneer je een taak ontvangt, is de eerste impuls om er onmiddellijk mee aan de slag te gaan, om geen tijd te verspillen. Maar het beleid 'we bevriezen het project totdat we in alle details zijn ingegaan' kan de verspilde tijd met hele orden verminderen.

Zelfs als je onder druk wordt gezet om te beginnen met werken terwijl je niet begrijpt waarom — weersta. Probeer eerst te begrijpen met welk doel je zo'n taak krijgt en bepaal of dit de juiste weg naar het doel is. Ik heb dit allemaal op de harde manier moeten leren — hopelijk maakt mijn voorbeeld het leven gemakkelijker voor degenen die dit lezen.

Vierde niveau van begrip: ???

In programmeren is er altijd iets te leren, en ik denk dat ik slechts de bovenste lagen van het begrip heb aangeraakt. Welke andere niveaus van begrip heb je ontdekt in de jaren dat je met code werkt? Welke beslissingen hebben een positieve invloed gehad op de kwaliteit van de code en de applicatie? Welke beslissingen bleken fout te zijn en hebben je een waardevolle les geleerd? Deel je ervaringen in de reacties.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster