Ga er niet mee akkoord om iets te ontwikkelen dat je niet begrijpt

Ga er niet mee akkoord om iets te ontwikkelen dat je niet begrijpt

Sinds begin 2018 bekleed ik de functie van lead/baas/lead developer in het team – noem het hoe je wilt, maar het punt is dat ik volledig verantwoordelijk ben voor één van de modules en voor alle ontwikkelaars die werken ben ermee bezig. Deze functie geeft mij een nieuw perspectief op het ontwikkelingsproces, omdat ik bij meer projecten betrokken ben en actiever betrokken ben bij de besluitvorming. Onlangs besefte ik dankzij deze twee dingen plotseling hoeveel invloed de mate van begrip heeft op de code en de toepassing.

Het punt dat ik wil maken is dat de kwaliteit van de code (en het eindproduct) nauw verband houdt met de mate waarin de mensen die de code ontwerpen en schrijven zich bewust zijn van wat ze doen.

Je denkt nu misschien: “Bedankt, Kapitein. Natuurlijk zou het leuk zijn om te begrijpen wat je in het algemeen schrijft. Anders kun je net zo goed een groep apen inhuren om willekeurige toetsen in te slaan en het daarbij laten.” En je hebt volkomen gelijk. Daarom neem ik het als vanzelfsprekend aan dat u zich realiseert dat het noodzakelijk is om een ​​algemeen idee te hebben van wat u doet. Dit kan het nulniveau van begrip worden genoemd, en we zullen het niet in detail analyseren. We zullen gedetailleerd bekijken wat u precies moet begrijpen en welke invloed dit heeft op de beslissingen die u elke dag neemt. Als ik deze dingen van tevoren had geweten, zou het me veel tijdverspilling en twijfelachtige code hebben bespaard.

Hoewel je hieronder geen enkele regel code zult zien, geloof ik nog steeds dat alles wat hier wordt gezegd van groot belang is voor het schrijven van hoogwaardige, expressieve code.

Eerste niveau van begrip: waarom werkt het niet?

Ontwikkelaars bereiken dit niveau meestal al heel vroeg in hun carrière, soms zelfs zonder enige hulp van anderen - althans in mijn ervaring. Stel je voor dat je een bugrapport hebt ontvangen: een functie in de applicatie werkt niet, deze moet worden opgelost. Hoe ga je verder?

Het standaardschema ziet er als volgt uit:

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

Laten we ons nu concentreren op het tweede punt: wijzigingen aanbrengen in de code. Er zijn twee benaderingen van dit proces. De eerste is om je te verdiepen in wat er precies gebeurt in de huidige code, de fout te identificeren en deze op te lossen. Ten tweede: ga op gevoel - voeg bijvoorbeeld +1 toe aan een voorwaardelijke verklaring of lus, kijk of de functie in het gewenste scenario werkt, probeer dan iets anders, enzovoort tot in het oneindige.

De eerste benadering is correct. Zoals Steve McConnell uitlegt in zijn boek Code Complete (wat ik trouwens ten zeerste aanbeveel), moeten we elke keer dat we iets in de code veranderen, met vertrouwen kunnen voorspellen hoe dit de toepassing zal beïnvloeden. Ik citeer uit mijn geheugen, maar als een bugfix niet werkt zoals je had verwacht, zou je erg ongerust moeten zijn en zou je je hele actieplan in twijfel moeten trekken.

Om samen te vatten wat er is gezegd: om een ​​goede bugfix uit te voeren die de kwaliteit van de code niet aantast, moet je zowel de volledige structuur van de code als de bron van het specifieke probleem begrijpen.

Tweede niveau van begrip: waarom werkt het?

Dit niveau wordt veel minder intuïtief begrepen dan het vorige. Ik, toen ik nog een beginnende ontwikkelaar was, leerde het dankzij mijn baas en legde vervolgens herhaaldelijk de essentie van de zaak uit aan nieuwkomers.

Stel je voor dat je deze keer twee bugrapporten tegelijk hebt ontvangen: de eerste gaat over scenario A, de tweede gaat over scenario B. In beide scenario's gebeurt er iets mis. Daarom pak je eerst de eerste bug aan. Met behulp van de principes die we hebben ontwikkeld voor inzicht op niveau XNUMX, graaf je diep in de code die relevant is voor het probleem, zoek je uit waarom deze ervoor zorgt dat de applicatie zich gedraagt ​​zoals in scenario A, en breng je redelijke aanpassingen aan die het gewenste resultaat opleveren. . Alles gaat geweldig.

Dan ga je verder met scenario B. Je herhaalt het scenario in een poging een fout uit te lokken, maar – verrassing! - nu werkt alles zoals het hoort. Om je gok te bevestigen, maak je de wijzigingen ongedaan die je hebt gemaakt terwijl je aan bug A werkte, en bug B komt terug. Uw bugfix heeft beide problemen opgelost. Gelukkig!

Je had hier helemaal niet op gerekend. Je hebt een manier bedacht om de fout in scenario A op te lossen, maar je hebt geen idee waarom dit werkte voor scenario B. In dit stadium is het erg verleidelijk om te denken dat beide taken met succes zijn voltooid. Dit is heel logisch: het ging erom fouten te elimineren, nietwaar? Maar het werk is nog niet klaar: je moet nog uitzoeken waarom jouw acties de fout in scenario B hebben gecorrigeerd. Waarom? Omdat het misschien volgens de verkeerde principes werkt, en dan zul je een andere uitweg moeten zoeken. Hier zijn een paar voorbeelden van dergelijke gevallen:

  • Omdat de oplossing niet was afgestemd op fout B, waarbij alle factoren in aanmerking worden genomen, is het mogelijk dat je onbewust functie C hebt verbroken.
  • Het is mogelijk dat er ergens nog een derde bug op de loer ligt, gerelateerd aan dezelfde functie, en jouw bugfix is ​​daarvan afhankelijk voor de juiste werking van het systeem in scenario B. Alles ziet er nu goed uit, maar op een dag zal deze derde bug worden opgemerkt en opgelost. Dan zal in scenario B de fout opnieuw optreden, en het is maar goed dat het daar is.

Dit alles voegt chaos toe aan de code en zal op een dag op je hoofd vallen - hoogstwaarschijnlijk op het meest ongelegen moment. Je zult je wilskracht moeten verzamelen om jezelf te dwingen tijd te besteden aan het begrijpen waarom alles lijkt te werken, maar het is de moeite waard.

Derde niveau van begrip: waarom werkt het?

Mijn recente inzicht heeft precies betrekking op dit niveau, en het is waarschijnlijk het niveau dat mij het meeste voordeel zou hebben opgeleverd als ik eerder op dit idee was gekomen.

Laten we, om het duidelijker te maken, naar een voorbeeld kijken: uw module moet compatibel worden gemaakt met functie X. U bent niet bijzonder bekend met functie X, maar er is u verteld dat u het F-framework moet gebruiken om ermee compatibel te zijn. modules die met X integreren, werken precies bij hem.

Jouw code heeft sinds de eerste dag van zijn bestaan ​​helemaal geen contact meer gehad met het F-framework, dus het implementeren ervan zal niet zo eenvoudig zijn. Dit zal ernstige gevolgen hebben voor sommige onderdelen van de module. Je stort je echter op de ontwikkeling: je bent weken bezig met het schrijven van code, testen, uitrollen van pilotversies, feedback krijgen, regressiefouten herstellen, onvoorziene complicaties ontdekken, de oorspronkelijk afgesproken deadlines niet halen, nog wat code schrijven, testen, feedback krijgen, communiceren, het corrigeren van regressiefouten - dit alles om het F-framework te implementeren.

En op een gegeven moment realiseer je je plotseling (of hoor je misschien van iemand) dat framework F je misschien helemaal geen compatibiliteit biedt met feature X. Misschien is al die tijd en moeite daar volkomen verkeerd in gestoken.

Iets soortgelijks gebeurde een keer tijdens het werken aan een project waarvoor ik verantwoordelijk was. Waarom is dit gebeurd? Omdat ik weinig begrip had van wat functie X was en hoe deze zich verhield tot raamwerk F. Wat had ik moeten doen? Vraag de persoon die de ontwikkelingstaak toevertrouwt om duidelijk uit te leggen hoe de beoogde handelwijze tot het gewenste resultaat leidt, in plaats van simpelweg te herhalen wat er voor andere modules is gedaan of hun woord ervan te geloven dat dit is wat feature X moet doen.

De ervaring met dit project heeft mij geleerd te weigeren aan het ontwikkelingsproces te beginnen totdat we duidelijk begrijpen waarom ons bepaalde dingen worden gevraagd. Weiger ronduit. Wanneer u een taak krijgt, is de eerste impuls om deze onmiddellijk aan te pakken, om geen tijd te verspillen. Maar het beleid ‘bevries het project totdat we op alle details ingaan’ kan de verspilde tijd met ordes van grootte terugdringen.

Zelfs als ze proberen druk op je uit te oefenen, je te dwingen aan het werk te gaan, ook al begrijp je de reden hiervoor niet, verzet je ertegen. Zoek eerst uit waarom u zo'n taak krijgt, en beslis of dit de juiste weg naar het doel is. Ik heb dit allemaal op de harde manier moeten leren - ik hoop dat mijn voorbeeld het leven gemakkelijker zal maken voor degenen die dit lezen.

Vierde niveau van begrip: ???

Er valt altijd meer te leren bij programmeren, en ik geloof dat ik nog maar het oppervlak van het onderwerp begrip heb betreden. Welke andere niveaus van begrip heb je ontdekt in de loop van de jaren dat je met code hebt gewerkt? Welke beslissingen heb je genomen die een positieve impact hadden op de kwaliteit van de code en applicatie? Welke beslissingen bleken verkeerd te zijn en hebben jou een waardevolle les geleerd? Deel uw ervaring in de reacties.

Bron: www.habr.com

Voeg een reactie