1. De taak van een programmeur
Heel vaak denken beginnende programmeurs heel anders over het werk van een programmeur dan ervaren programmeurs .
Beginners zeggen vaak iets als "Het programma werkt, wat heb je nog meer nodig?" Een ervaren programmeur weet dat "correct werken" slechts één van de vereisten is voor een programma , en dat is niet eens het belangrijkste !
Code leesbaarheid
Het belangrijkste is dat de programmacode begrijpelijk is voor andere programmeurs . Dit is belangrijker dan een correct werkend programma. Veel meer.
Als u een programma heeft dat niet correct werkt, kunt u dit repareren. Maar als je een programma hebt waarvan de code onbegrijpelijk is, kun je er niets mee.
Neem gewoon een willekeurig gecompileerd programma, zoals Kladblok, en verander de achtergrondkleur in rood. Je hebt een werkend programma, maar je hebt geen begrijpelijke broncode: het is onmogelijk om zo'n programma te wijzigen.
Een schoolvoorbeeld is toen Microsoft-ontwikkelaars het flipperspel uit Windows verwijderden omdat ze het niet konden overzetten naar een 64-bits architectuur. En ze hadden zelfs de broncode. Ze konden gewoon niet begrijpen hoe de code werkte .
Boekhouding voor elke use case
De tweede belangrijkste vereiste voor een programma is om rekening te houden met elk scenario. Vaak zijn dingen iets ingewikkelder dan ze lijken.
Hoe een beginnende programmeur het versturen van sms-berichten ziet:
Hoe een professionele programmeur het ziet:
Het scenario 'werkt correct' is meestal slechts een van de vele mogelijke. En daarom klagen veel nieuwelingen over de taakvalidator van CodeGym: slechts één van de tien scenario's werkt, en de nieuwe programmeur vindt dat genoeg.
2. Abnormale situaties
Bij de uitvoering van elk programma kunnen zich abnormale situaties voordoen.
U besluit bijvoorbeeld een bestand op te slaan, maar er is geen schijfruimte. Of het programma probeert gegevens naar het geheugen te schrijven, maar er is onvoldoende geheugen beschikbaar. Of u downloadt een afbeelding van internet, maar de verbinding valt weg tijdens het downloaden.
Voor elke abnormale situatie moet de programmeur (de auteur van het programma) a) erop anticiperen , b) beslissen hoe het programma het precies moet aanpakken , en c) een oplossing schrijven die de gewenste zo dicht mogelijk benadert.
Daarom hebben programma's lange tijd heel eenvoudig gedrag vertoond: als er een fout in het programma optrad, stopte het programma. En dat was een vrij goede aanpak.
Stel dat u een document op schijf wilt opslaan, tijdens het opslagproces ontdekt u dat er onvoldoende schijfruimte is. Welk gedrag zou je het liefst willen:
- Het programma wordt beëindigd
- Het programma blijft draaien, maar slaat het bestand niet op.
Een beginnende programmeur denkt misschien dat de tweede optie beter is, omdat het programma nog draait. Maar in werkelijkheid is dat niet zo.
Stel je voor dat je 3 uur lang een document in Word hebt getypt, maar na twee minuten schrijven werd duidelijk dat het programma het document niet op schijf zou kunnen opslaan. Is het beter om twee minuten werk of drie uur te verliezen?
Als het programma niet kan doen wat het moet doen, is het beter om het te laten sluiten dan te blijven doen alsof alles in orde is. Het beste wat een programma kan doen wanneer het een fout tegenkomt die het niet zelf kan oplossen, is het probleem onmiddellijk aan de gebruiker te melden.
3. Achtergrond over uitzonderingen
Programma's zijn niet de enigen die met abnormale situaties worden geconfronteerd. Ze komen ook voor in programma's - in methoden. Bijvoorbeeld:
- Een methode wil een bestand naar schijf schrijven, maar er is geen ruimte.
- Een methode wil een functie op een variabele aanroepen, maar de variabele is gelijk aan null.
- Delen door 0 gebeurt in een methode.
In dit geval zou de aanroepende methode de situatie mogelijk kunnen corrigeren (een alternatief scenario uitvoeren) als het weet wat voor soort probleem zich voordeed in de aangeroepen methode.
Als we proberen een bestand op schijf op te slaan en een dergelijk bestand bestaat al, kunnen we de gebruiker eenvoudig vragen om te bevestigen dat we het bestand moeten overschrijven. Als er geen beschikbare schijfruimte is, kunnen we een bericht aan de gebruiker tonen en de gebruiker vragen een andere schijf te selecteren. Maar als het programma onvoldoende geheugen heeft, crasht het.
Eens dachten programmeurs na over deze vraag en kwamen met de volgende oplossing: alle methoden/functies moeten een foutcode retourneren die het resultaat van hun uitvoering aangeeft. Als een functie perfect werkte, keerde deze terug 0 . Zo niet, dan retourneerde het een foutcode (niet nul).
Met deze benadering van fouten moesten programmeurs na bijna elke functieaanroep een controle toevoegen om te zien of de functie eindigde met een fout. Code werd enorm groot en zag er zo uit:
Code zonder foutafhandeling | Code met foutafhandeling |
---|---|
|
|
Bovendien wist een functie die ontdekte dat er een fout was opgetreden, vaak niet wat ze ermee moest doen: de beller moest de fout teruggeven, en de beller van de beller gaf het terug aan zijn beller, enzovoort.
In een groot programma is een aaneenschakeling van tientallen functieaanroepen de norm: soms vind je zelfs een aanroepdiepte van honderden functies. En nu moet je de foutcode van helemaal onderaan naar helemaal bovenaan doorgeven. En als ergens onderweg een functie de afsluitcode niet aankan, gaat de fout verloren.
Een ander nadeel van deze benadering is dat als functies een foutcode retourneerden, ze niet langer de resultaten van hun eigen werk konden retourneren. Het resultaat van berekeningen moest via referentieparameters worden doorgegeven. Dit maakte de code nog omslachtiger en verhoogde het aantal fouten verder.
GO TO FULL VERSION