1. Jobbet som programmør
Meget ofte tænker nybegyndere programmører på en programmørs arbejde helt anderledes, end hvordan erfarne programmører tænker på det.
Begyndere, der ofte siger noget som "Programmet virker, hvad har du ellers brug for?" En erfaren programmør ved, at "fungerer korrekt" kun er et af kravene til et program , og det er ikke engang det vigtigste !
Kode læsbarhed
Det vigtigste er, at programkoden er forståelig for andre programmører . Dette er vigtigere end et korrekt fungerende program. Meget mere.
Hvis du har et program, der ikke fungerer korrekt, kan du rette det. Men har du et program, hvis kode er uforståelig, kan du ikke gøre noget ved det.
Bare tag det kompilerede program, såsom notesblok, og skift dets baggrundsfarve til rød. Du har et fungerende program, men du har ikke forståelig kildekode: det er umuligt at lave ændringer i et program som dette.
Et lærebogseksempel er, da Microsoft-udviklere fjernede Pinball-spillet fra Windows, fordi de ikke kunne overføre det til 64-bit arkitektur. Og de havde endda dens kildekode. De kunne simpelthen ikke forstå, hvordan koden fungerede .
Regnskab for hver brugssag
Det næstvigtigste krav til et program er at tage højde for hvert scenarie. Ofte er tingene lidt mere komplicerede, end de ser ud til.
Sådan ser en nybegynder programmør afsendelse af SMS-beskeder:
Sådan ser en professionel programmør det:
Scenariet "fungerer korrekt" er normalt kun et mange muligt. Og det er derfor, mange nybegyndere klager over CodeGyms opgavevalidator: kun ét scenarie ud af 10 virker, og nybegynderprogrammøren mener, at det er nok.
2. Unormale situationer
Unormale situationer kan opstå i udførelsen af ethvert program.
For eksempel beslutter du dig for at gemme en fil, men der er ingen diskplads. Eller programmet forsøger at skrive data til hukommelsen, men den ledige hukommelse er lav. Eller du downloader et billede fra internettet, men forbindelsen afbrydes under downloadprocessen.
For hver unormal situation skal programmøren (forfatteren af programmet) a) forudse det, b) beslutte, hvordan programmet præcist skal håndtere det , og c) skrive en løsning, der er så tæt som muligt på den ønskede.
Det er derfor, programmer havde en meget enkel adfærd i ret lang tid: Hvis der opstod en fejl i programmet, blev programmet afsluttet. Og det var en ret god tilgang.
Lad os sige, at du vil gemme et dokument på disken, under lagringsprocessen opdager du, at der ikke er nok diskplads. Hvilken adfærd vil du bedst lide:
- Programmet afsluttes
- Programmet fortsætter med at køre, men gemmer ikke filen.
En nybegynder programmør tror måske, at den anden mulighed er bedre, fordi programmet stadig kører. Men i virkeligheden er det ikke sådan.
Forestil dig, at du skrev et dokument ud i Word i 3 timer, men to minutter inde i din skriveproces blev det klart, at programmet ikke ville være i stand til at gemme dokumentet på disken. Er det bedre at miste to minutters arbejde eller tre timer?
Hvis programmet ikke kan, hvad det skal, er det bedre at lade det lukke, end at fortsætte med at lade som om alt er okay. Det bedste, som et program kan gøre, når det støder på en fejl, som det ikke kan løse på egen hånd, er straks at rapportere problemet til brugeren.
3. Baggrund om undtagelser
Programmer er ikke de eneste, der står over for unormale situationer. De forekommer også i programmer - i metoder. For eksempel:
- En metode ønsker at skrive en fil til disk, men der er ingen plads.
- En metode ønsker at kalde en funktion på en variabel, men variablen er lig null.
- Division med 0 sker i en metode.
I dette tilfælde kunne den kaldende metode muligvis rette situationen (udføre et alternativt scenarie), hvis den ved, hvilken slags problem der opstod i den kaldte metode.
Hvis vi forsøger at gemme en fil på disken, og en sådan fil allerede eksisterer, kan vi blot bede brugeren om at bekræfte, at vi skal overskrive filen. Hvis der ikke er ledig diskplads, kan vi vise en besked til brugeren og bede brugeren om at vælge en anden disk. Men hvis programmet løber tør for hukommelse, vil det gå ned.
Engang overvejede programmører dette spørgsmål og fandt på følgende løsning: alle metoder/funktioner skal returnere en fejlkode, der angiver resultatet af deres udførelse. Hvis en funktion fungerede perfekt, returnerede den 0 . Hvis ikke, returnerede den en fejlkode (ikke nul).
Med denne tilgang til fejl, efter næsten hvert funktionskald, måtte programmører tilføje et tjek for at se, om funktionen sluttede med en fejl. Koden blev ballonformet i størrelse og kom til at se sådan ud:
Kode uden fejlhåndtering | Kode med fejlhåndtering |
---|---|
|
|
Desuden vidste en funktion, der opdagede, at der opstod en fejl, ofte ikke, hvad den skulle gøre med den: den, der ringer, skulle returnere fejlen, og den, der ringer, returnerede den til den, der ringer, og så videre.
I et stort program er en kæde af snesevis af funktionsopkald normen: nogle gange kan du endda finde en opkaldsdybde på hundredvis af funktioner. Og nu skal du videregive fejlkoden fra bunden til toppen. Og hvis et eller andet sted undervejs en funktion ikke håndterer udgangskoden, så vil fejlen gå tabt.
En anden ulempe ved denne tilgang er, at hvis funktioner returnerede en fejlkode, kunne de ikke længere returnere resultaterne af deres eget arbejde. Resultatet af beregninger skulle videregives via referenceparametre. Dette gjorde koden endnu mere besværlig og øgede yderligere antallet af fejl.
GO TO FULL VERSION