Hvad er god kode?

I sidste måned skrev Prosabladet en del om god kode, som fik mig til at tænke - hvordan genkender man god kode og hvordan lærer man at skrive det' Jeg vil påstå at jeg ikke lærte ret meget om god kode på universitetet - jojo jeg lærte noget om test (og TDD), design patterns og på første år fik vi også reviewet noget kode, men siden det første år har jeg ikke prøvet at få feedback på min kode - de teoretiske principper var det vi blev vurderet på.

Nu sidder jeg så på et større kodeprojekt, hvor god kode virkelig er i fokus og lysten har meldt sig til at forbedre min kodestil. Jeg startede med at kigge på SOLID-pricipperne, læse og prøveimplementere et par designpatterns, kigge i Fowlers bog om refactoring, investere i bogen Clean Code og begyndt at følge et par spændende sites såsom Onkel Bobs og Ayendes blogs.

Men jeg er stadig på jagt på svar; hvordan genkender man god kode' Hvordan ved du at den kode du skriver er god' Hvor kan man finde brugbare råd omkring god kode' Kender du nogle gode bøger'

Kommentarer (51)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Kent Damgaard

Min vinkel på spørgsmålet er nok præget af at jeg har været konsulent i en række år, så jeg synes at en vigtig parameter må være om en anden kan tage koden og rette i den når det bliver nødvendigt.

Nogen gange kan de være godt lige at slippe tastaturet og tænke "ville jeg selv have lyst til at skulle gå tilbage og rette i det her efter seks måneder hvor jeg har lavet alt muligt andet". Nogen gange kan god kode også være dårlig kode der lærer en at det skal man ihvertfald lade være med at gøre en anden gang.

God kode skal ikke bevise ophavsmandens genialitet, den skal bevise sin levedygtighed. Det er bedre at skrive en krimi der kan læses med interesse af de fleste end et knudret mesterværk for en lille elite - med mindre det er noget man regner med at skulle vedligeholde og bygge videre på resten af livet, i så fald så gå til den :-)

Patterns er godt, med måde, det er godt at læse den indledende del og forstå principperne i GOF bogen, men skidt hvis man efterfølgende strør om sig med patterns overalt, uanset om de er brugbare eller ej, for at vise at man kan dem.

Jeg har tre bøger jeg vil anbefale. "The Pragmatic Programmer" af Hunt og Thomas. "Writing solid code" af Steve Maguire og "Code complete" af Steve McConnell.

  • 0
  • 0
Poul-Henning Kamp Blogger

"God kode" er en kvalitetsmetrik og sådanne kan sjældent, hvis nogensinde, måles som andet end en konsensus derom.

Der er ikke mange der ikke opfatter Margretheskålen eller Rådvads urtekniv som kvalitet, men der er ikke ret mange der kan fortælle hvorfor de har den opfattelse.

En af de bedste formuleringer jeg har hørt, var en eller anden designprofessor i P1 for mange år siden, der sagde at for værktøjer, er kvalitet ofte lig tilliden til at værktøjet er forudsigeligt og ikke svigter.

Han mente at den eneste grund til at B&O havde et ry for kvalitet var at betjeningen blot krævede at man trykkede "play" så ville der komme lyd ud, i modsætning til datidens knap-orgier fra Japan. Den mekanisk/elektriske kvalitet af B&O mente han var noget under gennemsnit.

De karakteristika der går igen i god kode, er generalitet, konsistens og et klart og sparsomt udtryk.

Eller sagt på en anden måde: Hvis det er god kode, er du ikke i tvivl om hvad det gør.

Grundbogen du skal læse er "Zen and the art of Motorcycle Maintenance".

Poul-Henning

PS: Det tager omkring 15-20 år at lære at skrive god kode.

  • 0
  • 0
Søren Lund

Jeg har altid tænkt på koden, som udviklerens primære adgang til "systemet". Derfor skal koden overholde mange af de samme principper som brugergrænseflader.

Kode skal f.eks. være velstruktureret, den skal være konsistent og den skal undgå støj.

Velstruktureret kode er nem at navigere i, og vil se "pæn ud", hvilket giver en lyst til/glæde ved at arbejde med koden.

Konsistens kommer blandt andet fra brug af en kodestandard, der ikke kun omhandler generelle ting (f.eks. navngivningsregler), men også kunde-/systemspecifikke regler.

Støj kan f.eks. være for mange kommentarer:
[code=c]
int n; // Number of lines
[/code]
et klassisk eksempel på støj (variablen n skal selvfølgelig bare hedde number_of_lines).

Det samme gælder kommentarer, der forklarer funktioner/metoder/algoritmer. I stedet for en funktion, der henter en xml-fil, indlæser den, opdaterer en database og skriver til en log-fil. Skal funktionen kalde fire funktioner: read_xml, parse_xml, update_database og write_to_log. Hermed er funktionen dokumenteret direkte i koden og ingen kommentarer er nødvendige. Desuden er koden blevet meget lettere at teste.

Støj er også unødvendig kode. Hvis der kun er brug for to metoder på en objekt, så lad være med at implementere alle mulige varianter.

Det er i øvrigt lettere at genkende dårlig kode, der kan de fleste blive enige ;-)

  • 0
  • 0
Magnus Lund

når man 6 måneder senere kan kigge koden igennem og tænke "Det ser sgu egentlig meget fornuftigt ud" og man rent faktisk kan se, hvad koden gør.

Og nej, jeg er endnu ikke nået til det punkt :-). Jeg krøller som regel tæer når jeg kigger på kode, jeg skrev for 6 måneder siden.

God kode rent forretningsmæssigt er når skidtet tjener penge hjem. Dvs. når tiden til at skrive den (og vedligeholde den i dens levetid) kan hentes hjem fra omsætning til kunder.

  • 0
  • 0
Nikolaj Brinch Jørgensen

..kode som ikke er dårlig kode.

Det er et super godt spørgsmål, for nogen lærer det aldrig, og er også ligeglade. De laver tilmed den legendariske copy+paste programmering. F.eks. med et tilpas erfaringsgrundlg der gør det, skal man nok skulle sig af med, for de kan holde både sigselv og andre beskæftiget med fejlrettelser.

Det der egenligt er bekymrende er at der tit måles på mængden af kode der kan skrives. En kollega og jeg joker nogen gange om at man burde betale os for al den koden vi kan slette fra kundernes systemer.

Med god kode er det lidt a la Ludwig Mies Van Der Rohe "Less is more".

Hvis koden er god vil den også kunne udtrykke hvad den gør klart på en overskuelig mængde plads.

Dårlig kode har det med at få sådan et liv hvor den bare breder sig som fejlene begynder at blive rapporteret ind. Det er her man skal stoppe op og vide at koden ikke er god.

  • 0
  • 0
Jens Madsen

Når store softwareprojekter ikke fungerer, skyldes det faktorer som belastning, manglende dimmensionering, fejl eller manglende overvejelser i algorithmer, osv. Meget sjældent, skyldes det at en person kalder en variabel for n - fremfor "number_of_lines". Vores dataloger, der i sin tid underviste i programmering, insisterede faktisk på at kalde kalde number of lines for n, og så deffinere det hvor det blev indført, og ikke hver eneste gang det blev anvendt. At have hele teksten i variabelen gav ingen mening. Skriv den sammen med erklæringen. Her er plads, og det kan uddybes ordentligt, var holdningen. Fremfor, at skulle skrive samme roman hver gang, med copy og paste.

Når vi kommer til, at man taler om god kode - og diskuterer hvorvidt man skal skrive n, eller number_of_lines, så tror jeg vi er derude, hvor det er børn der diskuterer, som ikke formår at udvikle algorithmer der har hurtig svartid, og analysere problemstillingerne grundigt. Problemerne ligger oftest i manglende eller dårlig analyse og design. Ikke i, om man skriver n, eller number of lines.

Dem, der går op i det, plejer at være dem der intet kan. Som dem, der går op i stavefejl, i stedet for indhold.

Det som er problemet i det meste kode, er faktisk indholdet. De bruger algorithmer der ikke dur, har ikke overvejet store O funktioner, kan ikke "opfinde" metoder med rimelig svartid, anvender overkomplicerede metoder, osv. Ofte, beskrives problemerne i megakode, hvor der kunne være udviklet et system, der ikke kunne fejle, og hvor koden fyldte langt mindre. Problemet i kode, er den manglende datalogi. Selv søgealgorithmer, er der mange der ikke kan udvikle selv. Så, de kan "kun" programmere objektorienteret. Det er egentligt også i orden - hvis de så bare kan så meget selv, at de kan vurdere de ting de bruger eller køber. Men, man skal som minimum have kendskab til, hvor godt det kan gøres og gerne hvordan, for at vurdere om et tool, biblioteker og objekte, er gode nok, i forhold til det mulige.

Jeg har egentligt ikke noget imod, at nogen kalder number_of_lines, for n. Faktisk synes jeg, det er det eneste rigtige, og mener at koden bliver stor, kluntet og grim, hvis der står "number of lines" hver eneste gang. Dette afhænger dog af hvor det bruges. Hvis det er en global statisk variabel, eller konstant, der bruges over mange sider - og som bruges relativt sjældent, med stor afstand mellem hver gang - så må den gerne fylde nogle flere bogstaver, og indeholde noget lidt mere beskrivende. Men, har du en rutine, eller algorithme, der fylder 7 linier, så mener jeg klart du skal kalde number of lines for n, og skrive det umiddelbart før ved erklæringen, hvad at n indeholder. I sprog som C og C++, har du mulighed for lokale variable, i dit pågældende skop, og du kan derfor nemt have defineret den, og beskrive variablen, umiddelbart før brugen af den. For mig, ligner det fuldemandstekst, at gentage det samme igen og igen.

Hvis derimod, at det er en global variabel, som indeholder number of lines - og dette gælder for hele programmet - så er det noget andet. Så skal den hedde "number_of_lines".

Jeg kan nemt leve med en algorithme, formel, eller lign. der fylder nogle få linier i et program, og hvor der bruges bogstaver som a, b, x, n og lign. og så er beskrevet hvad de pågældende variable indeholder, samtidigt med de er erklæret umiddelbart før, f.eks. ved starten af det pågældende skop.

Og jeg synes faktisk, at det er mest korrekt, for matematiske formler. Hvem har set en matematikbog, hvor der står navne? Det bliver formlerne uoverskuelige af. Og sådan er det også med programmer.

Ofte, er der matematik eller datalogi bag formler og algorithmer. At skulle beskrive den, i programmet, er også tåbeligt. Hvorfor, skulle man gennemgå newtons samlede værker, når man beskriver der indtastes newtons 2. lov? Advanceret matematik og datalogi, hører ikke til i programmet, men i dokumentationen, og eventuelt i værker, som der kan henvises til. Programmet, kan så henvise til dokumentationen, og f.eks. til formlens navn, eller nummer.

Er det meget simpelt, kan det måske beskrives i programmet. Men, igen, ser jeg ingen problemer i, at nogle kalder ubekendt eller unknown for X eller U.

Der, hvor jeg bliver sur, er hvis kompleksiteten af noget, ikke er overvejet, så det tager en evighed, før at rutinen returnerer. Eller, hvis man ikke har styr på sine ting, f.eks. ikke anvender et system, så man undgår memory leaks.

Navngivningen, er som sådan ligegyldigt for essensen. Og det er som regel essensen, der fejler, for de fleste programmører!

  • 0
  • 0
Nikolaj Brinch Jørgensen

Er det meget simpelt, kan det måske beskrives i programmet. Men, igen, ser jeg ingen problemer i, at nogle kalder ubekendt eller unknown for X eller U.

Der, hvor jeg bliver sur, er hvis kompleksiteten af noget, ikke er overvejet, så det tager en evighed, før at rutinen returnerer. Eller, hvis man ikke har styr på sine ting, f.eks. ikke anvender et system, så man undgår memory leaks.

Navngivningen, er som sådan ligegyldigt for essensen. Og det er som regel essensen, der fejler, for de fleste programmører!

Det er ok du ikke har noget problem med det.
Men i store forretningssystemer er det tit objektorienteret programmering der laves.
Her har objekterne attributter en mapning til virkeligheden og er ikke en del af formler eller søgerutine, træstrukturer eller lignende (det ligge gemt i standard-biblioteket).
Her er det rart at folk kalder fornavn fornavn eller firstName - ligesom det er skrevet i data dicotionary, så det bibeholder mapningen rundt i systemt. Dette kaldes konsistens og er en af de første ting i god kode. Vær konsistent i din kode - ligesom funktioner og metoder skal have navne efter hvad det er de laver og hvilket ansvar de har.

Husk at kode ligesom bøger og emails skrives en gang, men læses rigtig mange. Derfor skal man gøre sig umage med at skrive den/dem. Derfor er det ikke lige meget. Du har din personlige stil jeg har min.
Jeg holder mig normalt til den stil der er de facto på området. For Java er det Sun Java coding conventions. At lave nogle andre er i mine øjne spild af tid og penge.

  • 0
  • 0
Carsten Sonne

God kode løser nogle krav/behov på en så kort og præcis måde som muligt uden samtidig af være så specifik at udvidelse og tilpasning kræver en væsentlig omskrivning. Det sværeste er at gennemskue nutidige og fremtidige behov så unødigt kompleks og unødigt generisk kode kan undgås.

Kode konventioner er en smagssag/politik og er i udgangspunktet ikke relevant ift. begrebet 'god kode'.

  • 0
  • 0
Jens Madsen

De tilfælde som du nævner, har en vis "global" karakter, fordi det er tale om globale konvektioner. Og så er det også stor mening i, at kalde det noget sigende, og det samme hver gang.

For en algorithme, hvor f.eks. number_of_lines overføres til, og hvor at algorithmen også kan bruges til andre formål, kan det være god fornuft i at bruge n. Ingen ved reelt, om at n er number_of_lines, og at bruge n i selve algorithmen er derfor bedre end at bruge number_of_lines. Selvom n, måske i algorithmen er number of lines der skal sorteres, så kan det måske være relevant at kalde det n, da det måske ikke er det samme som number_of_lines.

Det som jeg synes har størst betydning, er analyse og design. At anvende algorithmer, hvor man har overblik over svartid, og forbruget af hukommelse. Og at anvende metoder, så man ikke får memory leaks. Bruger man rutiner, tools, komponenter, biblioteker osv. så at gøre et ordentligt forarbejde, så man ved hvordan de arbejder - og kender til deres svartid, store O kompleksitet, hukommelsesforbrug, og om der er leaks eller andre problemer.

Er det tale om variable, eller konstante, der har lange "levetider", synes jeg også, at det er relevant, at bruge sigende variablenavne, selvom de måske fylder lidt. Men, gør den lange tekst, så f.eks. en formel uoverskueligt, synes jeg det er fint, at man i lokale variable med korte levetider, sætter variable lig de lange, og bruger f.eks. a, b, n osv. og herefter gemmer resultatet i en "lang" variabelnavn, der er sigende. Små, lokale variable, af midlertidigt karakter, må efter min opfattelse godt være korte. Men, det skal være tydeligt, hvad de indeholder, og være erklæret og beskrevet overskueligt, umiddelbart før.

Som eksempel, accepterer jeg også et lokal loop, hvor i er en tællevariabel, og hvor der ved erklæringen står tællevariabel, counts, eller lign. som kommentar. Ingen grund til, at kalde den "mere" end i, når den er lokal. Derimod, er ikke tilladt, at have en global tællevariabel, der hedder i, uanset det måtte give mening, at man vil kunne bruge samme tællevariabel rundt i programmet.

Et eksempel, på konvektioner jeg vil være modstander af, er at kalde number_of_lines, for Number_of_lines, med stort forbogstav i tilfælde, hvor det har anden betydning. Eller bruge store I, og lille i, i en tælleløkke med en underløkke. Så er bedre at bruge ii, og iii for "underløkker".

  • 0
  • 0
Claus Jørgensen

Lad folk der har nul indsigt i hvad din kode gør lave et review af den. Hvis de ikke kan gennemskue funktionaliteten, så er det ikke god kode. IRC er et rigtig godt sted at få lavet reviews.

Derudover er der nogle tommelfinger regler:

  • Altid følg kode-konventionerne, evt. lade dit IDE rette din kode til automatisk, så det er velformatteret.

  • Forsøg at kode funktionelt, fordi du i større grad vil splitte funktionalitet op, og samtidig undgå problemer senere i forløbet.

  • Kommentarer i koden bør være overflødigt, i stedet bør API dokumentationen beskrive hvilken algoritme der er implementeret samt hvordan.

  • Programmer efter det sprog du arbejder i, hvis du koder i C#, skal du ikke kode Java, og hvis du koder i C++ skal du ikke kode C.

  • Brug rigtige variable-navne, ikke forkortelser. Der er ikke noget værre end navngivning ala. WINAPI / hungarian notation etc.

Derudover overrasket det mig at der ikke har været undervisning i god kode, eller at forlæserne ikke har sørget for at det er en del af undervisningen.

Nogle tutorer kunne måske have hjulpet, men det er min erfaring at de fleste studerende er hamrende ligeglade med god kode, indtil de får sig et arbejde. Folk kan ikke se pointen med det i deres små studieprojekter i diverse rodede nichesprog, hvor kodestilen ikke giver ekstra points hos professoren.

  • 0
  • 0
Nikolaj Brinch Jørgensen

Kode konventioner er en smagssag/politik og er i udgangspunktet ikke relevant ift. begrebet 'god kode'.

Ikke korrekt. Måske ikke for dig, men det har det så for nogle af os andre. I nogle tilfælde (Python) kan det være indbygget i syntaksen.

Der findes flere værktøjer som kan laves statisk metrik måling på kode for at se om den som minimum lever op til en bare nogenlunde hæderlig standard. (Til Java er der f.eks. PMD/CPD, Checkstyle, FindBugs, McCabe osv.) Det ville være fordelagtigt om man allerede tidligt i sit forløb som programmør fik aflært evt. dårlige vaner meget ridligt. Eller muligvis ikke fik tillært dem overhovedet.

Claus er inde på noget af det rigtige. Giv point for kodestil og beautiful kode.

Dette bør være mandatory på ethvert studie der overhovedet beskæftiger sig med programmering
http://rubyhoedown2007.confreaks.com/session09.html

@Jens Madsen:
Variable mapper til virkeligheden, derfor er det smartest at give dem sigende navne. Når du tildeler dine variable i dine algortimer 1 bogstavs navne, er det jo fordi de mapper til algoritmerne i matematikken som du selv siger, og her har de også 1 bogstavs navne der er blevet til vha. konventioner (matematikkens data dictionary).

Desuden er copy/paste omkring variable overflødigt med en ordentlig code-complete editor.

  • 0
  • 0
Kasper Birch Olsen

Det er simpelt at fortælle hvorfor kode er dårlig når man ser den. Jeg så fornyeligt noget kode (som indgik i et kundeprojekt) hvor "udvikleren" brugte try/catch til at kontrollere flow, i stedet for if/else osv. Det er jo ingen sag at påpege hvorfor det er elendigt.

Problemet er bare at god kode ikke er kode der ikke er dårlig. God kode er mere end det, og det springet fra "kode der ikke er dårlig" til "god kode" der er svært at definere.

Navngivning, designpatterns, læsbarhed, vedligeholdbarhed osv. er alt sammen vigtige input for god kode, men også nærmest umuligt at måle.

  • 0
  • 0
Kasper Birch Olsen

Jeg er helt enig i ovenstående punkter, men der mangler en:

  • Undgå "smart" semantik.

Jeg kan ikke udestå når der er en eller anden udvikler der viser mig hvordan han har lavet en utrolig smart funktion og fået kogt 30 linjer kode ned til 2 linjer som så til gengæld er ulæselige. Jeg vil meget hellere have koden til at fylde nogle ekstra linjer og være let at læse, end jeg vil forsøge at gennemskue 2-3 linjer sort snak.

  • 0
  • 0
Kent Damgaard

Meget enig.

En der er lidt i samme boldgade er når sproget tillader konstruktioner der kan føre til fejl senere, så er det bedst ikke at bruge dem.

For eksempel kan man i Java undlade at bruge tuborg parenteser i if-else konstruktioner hvis det der skal udføres kun er en enkelt linje. Men det er let senere at overse når man skal tilføje en linje mere til else konstruktionen, og så sidder man og undrer sig over hvorfor programmet gør mærkelige ting.

Så nogen gange kan det godt betale sig at lave en konstruktion der fylder lidt mere, men som hjælper den næste programmør når der skal laves en hasterettelse i en sen nattetime :-)

  • 0
  • 0
Kent Damgaard

En af grundene til at kommentarer ofte ender med at være støj er, at folk lærer at de skal skrive kommentarer, men ikke hvad gode kommentarer er.

Derfor får man tit kommentarer der beskriver ting der umiddelbart fremgår af koden, som "her indlæses xml filen", men som sjældent beskriver intentionen i koden.

Tit ser man "this is an ugly hack" eller "omgåelse af fejl" i stedet for "nedenstående er en omgåelse på grund af bug 3434 i XML parseren. Når leverandøren har rettet den kan vi i stedet bruge de tre nedenstående udkommenterede linjer".

Og så skal vedligeholdelsesprogrammøren selvfølgelig huske at læse og opdatere kommentaren så hans efterfølger ikke skal undre sig over at kommentar og kode nu ikke længere passer sammen :-)

  • 0
  • 0
Nikolaj Brinch Jørgensen
  • Undgå "smart" semantik.

Det er jeg enig i, hvis vi snakker om der hvor kode bliver ulæseligt. Hvis dette går på at man ikke må kave kode som er smuk og kort, og som kræver at man sætter sig ind i det, i stedet for at copy/paste kæmpe blokke er jeg uenig.

F.eks. kræver funktionelle programmerings aspekter og f.eks. closures, at man har et vist niveau. Det vil være synd at bandlyse disse fordi nogle få ikke kan finde ud af at bruge dem til at lave ordentlig kode med.

Jeg synes at det at kode efter "laveste fællesnævner" på ingen måde kan føre til god kode.

Der er gode programmører og dårlige. Ligesom det er med andre håndværkere. Og nogle bliver aldrig gode til det, mest af alt også fordi de ikke har interessen. En god racerkører han træner, det samme gør en god programmør.

  • 0
  • 0
Poul-Henning Kamp Blogger

Tit ser man "this is an ugly hack" [...]

Præcis som skiltet med "skarp kurve forude" har reddet bilister fra buler, har den slags kommentarer en plads i kildetekster.

En sådan kommentar havde f.eks været helt på sin ret i Debians herostratisk berømte entropi-initialisering og havde måske forhindret en dumhed.

Poul-Henning

PS: Den mest berømte kommentar i denne klasse er naturligvis:

/* You're not expected to understand this */

se: http://cm.bell-labs.com/cm/cs/who/dmr/odd.html

  • 0
  • 0
Daniel Madsen

.. kommer med erfaring, hvis man stræber efter det.

Hvis man ikke har det som en prioritet, kan man skrive dårlig kode i 10 år uden at det er blevet mere læsevenligt eller vedligeholdelsesbart for andre (dette er de primære parametrer for god kode efter min mening).

Mange tillægger sig nemlig i de første år af deres karriere en bestemt kodestil, som de har svært ved at afvige særlig meget fra. Det bliver hurtigt til vanetænkning.

Så det vigtigste i forhold til at opnå at skrive god kode, er at man interesserer sig for at skrive god kode og er villig til at revidere sin måde at skrive kode på løbende (identificer dårlige vaner og gør noget ved dem).

Nogle generelle råd:

  • Gør brug af abstraktioner. De færreste forstår at opdele deres kode godt nok og godt opdelt kode er alfa og omega for om koden er overskuelig. Dette gælder på alle niveauer: Biblioteker, klasser, funktioner.

  • Biblioteker: Identificer delsystemer der kan placeres i selvstændige biblioteker (under Windows typisk som DLL'er). Mange bruger for lidt tid på dette og blander tit tingene sammen i store DLL'er, som hurtigt bliver rodede. Hvis det navn du har givet DLL'en er for generelt "Functions.dll f.eks." er det ofte et symptom på at koden ikke er skarpt nok opdelt. Bibliotekets navn skal gerne specificere konkret funktionalitet og koden afspejle dette (f.eks. "HTMLParser.dll")

  • Klasser: Det er samme grundlæggende problem her, mange blander typisk for meget sammen i den samme klasse. Sørg for at klasserne er godt navngivet efter den funktionalitet de implementerer og kun implementerer den funktionalitet klassens navn giver udtryk for. Tit ser man at der blandes for meget sammen i en klasse, som burde have været spredt ud over 2-3 eller måske flere klasser. Min tommelfingerregel er at når en klasse begynder at nå ud over 150 linjers konkret kode, så er det tid til at stoppe op og overveje om den muligvis spreder sig over et for stort ansvarsområde (Dermed ikke sagt at klasser ikke må nå ud over 150 linjers konkret kode, men det skal isåfald være en velovervejet beslutning og være mere undtagelsen end reglen)

  • Funktioner: Igen placeres for meget ansvar ofte i én funktion istedetfor at den deles op i en public funktion og 2-3 private hjælpefunktioner. Igen er min tommelfingerregel at hvis en funktion begynder at nå ud over 15 kodelinjer, så stop op og overvej om ikke der er dele af den der kan skilles ud i en tilpas navngivet hjælpefunktion. Sørg også for at især public funktioner er godt navngivet, det er trodsalt hovedsageligt disse andre skal formå at bruge nogenlunde intuitivt.

  • God kode er i høj grad selvdokumenterende. Undgå at plastre koden til med kommentarer, det skader ofte læsbarheden mere end det gavner. Overvej dit publikum når du anvender kommentarer, hvis du skriver al din kode i et højlevel sprog som .NET og med få undtagelser laver nogle WinAPI kald, kan det godt være at det giver mening at kommentere på brugen af disse, men hvis du er ved at implementere et lowlevel socket-biblikotek i .NET så må det tilgengæld forventes at folk der skal læse din kode forstår grundlæggende WinAPI kald og ved hvor de kan finde dokumentation på disse.

Det er også værd at bemærke at det faktisk ikke tager længere tid at skrive god kode, tværtimod resulterer et godt kodedesign ofte i at nogle problemer er nemmere at løse. Det eneste der tager lidt ekstra tid er at revidere sin kodestil og tillære sig nogle bedrer vaner, en invistering der hurtigt betaler sig selv hjem.

  • 0
  • 0
Carsten Sonne

Kode konventioner er en smagssag/politik og er [b]i udgangspunktet[/b] ikke relevant ift. begrebet 'god kode'.

Kodekonventioner er selvfølgelig en del af 'god kode'. Der dog en del parametre, som ikke er så generiske på tværs af platforme og sprog.

Det eneste rigtige generiske element, men selvfølgelig stadig meget vigtig er:

Konsistens er den del af begrebet 'god kode'...

Navngivningsstandarder bør følge 'Best Pratice' inden for sproget/platformen og være i trit med den offentlige API. Såfremt IDE'et understøtter en slags 'code completion', bør sigende navne bruges på alle identifiers, variabler, funktioner, metoder etc.

OO sprog har deres egen Best Practice kodekonventioner. Ligeledes har andre typer sprog. Disse bør selvfølgelig følges.

Statisk kodeanalyse kan give en ide om uheldig sprogbrug og være en kod kilde til udarbejdelse af en kodekonvention. Disse konvention variere enorm fra sprog til sprog. Noget der bliver betragtet som Best Practice i et sprog kan være Worst Practice i et andet, grundet sproget, afviklingsmiljøet og ikke mindst udvikler-miljøet (menneskerne).

Formålet skal altid holder for øje. Kodekonventioner er primært til for at lette arbejdet på tværs af udviklere og for at øge kodekvaliteten ift. fejl, vedligeholdelse og robusthed. Så længe man holder målet for øje, kan det ikke gå helt galt.

  • 0
  • 0
Carsten Sonne

Der er altid trade-offs når man vælge en implementering. En klassisk teknisk tradeoff er hukommelsesforbrug vs CPU tid. En langt vigtige er omkostning i ressourcer (tid, penge, energi) vs. god kode. God kode tager tid og du rammer aldrig rigtig første gang. God gode er typisk refaktoriseret et antal gang før det får sin enelige form.

Diverse trade-offs skal man gøre sig klart. Man kan ikke få alt og må vælge det der er vigtigst i situationen. Man bør være bevidst om diverse trade-offs og aktivt forsøge at lave de rigtige valg.

  • 0
  • 0
Claus Jørgensen

Det fik mig til at tænke på at en kompiler tit kan optimere ens kode ret meget, så man skal ikke forsøge at skrive ulæsbar kode, hvis det alligevel har nul effekt på koden efter kompilation.

Specielt i Java og C#.

  • 0
  • 0
Claus Jørgensen
  • Undgå "smart" semantik.

I .NET regi er der meget diskussion omkring brugen af lambda og LINQ. Men er det så meget dårligere brug af sematik?

var superPositives = users.Where(user => user.Karma >= 10);

versus at skulle definere en collection, et loop, og en if-sætning.

Det handler om at koden er selvindlysende, og læsbar. Ikke om sematikken er "smart" eller ej.

Men jeg tror også at problemet med "smart" semantik er mere typisk i perl/python/ruby/haskell som tillader en del sjove language constructors.

Men vil du f.eks. klassificere en monad i haskell som "smart" semantik, eller smart programmering?

  • 0
  • 0
Jesper Louis Andersen

Men vil du f.eks. klassificere en monad i haskell som "smart" semantik, eller smart programmering?

Monads er bare et værktøj, som kan misbruges i samme grad som andre sprogkonstruktioner. Anvendt rigtigt øger de læsbarheden af kode betragteligt. Anvendt forkert gør de kode meget svært at læse. Selvfølgelig er der også en del tilvænning indblandet: Jo flere gange du ser et idiom, des lettere er det at følge og forstå.

Min erfaring er at god kode:

Minimerer mutabilitet - altså laver så få direkte tilstandsopdateringer som muligt. Fejl opstår som regel når koden ændrer i tilstanden, så jo mere man kan kontrollere det, jo bedre kode (med måde naturligvis - tilstandsopdateringer er centralt for programmering).

Gør ulovlige tilstande urepræsenterbare - Du kan ikke få fejl fra en given tilstand hvis programmet aldrig kan bringes i den tilstand på nogen vis. Statiske typesystemer hjælper en hel del her fordi et heltal ikke pludselig er en streng (typesystemet vil gøre det urepræsenterbart). Eller at en streng ikke kan være NULL på et givent sted (her fejler eksempeltvist Java og C, men ML og Haskell har det rigtigt). Man kan aggressivt programmere mod at ulovlige tilstande er ikke-repræsenterbare og det giver som regel god kode. Ikke mindst fordi der er meget få hjørnetilfælde man skal gardere sig i mod.

  • 0
  • 0
Poul-Henning Kamp Blogger

[quote]God kode tager tid og du rammer aldrig rigtig første gang

Hmm, uenig. Dårlig kode tager tid.
Dårlig kode kræver konstant vedligeholdelse.
[/quote]

Nej, God kode tager tid og kræver mindst 2 forsøg.

Eller some FPB har belært os i 35 år:

Plan to write a prototype and plan to throw it out, because you will do so, even if you do not call it a prototype or ship it to customers

Det er faktisk efterhånden blevet mainstream, nu hedder det blot "refactoring the first version".

Det er blot C-team new-speak, på samme måde som "trial & error" kom til at hedde "prototyping".

Poul-Henning

  • 0
  • 0
Carsten Sonne

GRASP (General Responsibility Assignment Software Patterns) er et uvurderligt sæt grundregler for god OO kode. De beskriver bl.a. høj samhørighed, lav kobling og 'Information Expert'. Information Expert bør efter min mening, være det det basale princip i alt OO kode.

Det er dog mere ovre i OOAD boldgaden og kan nok nærmere betragtes som god kode på et højere niveau aka. designniveau. Ikke at det er uvæsentligt af den årsag, tværtimod.

  • 0
  • 0
Poul-Henning Kamp Blogger

GRASP (General Responsibility Assignment Software Patterns)[...]

Det lyder som titlen på en bog man ville finde i lufthavnens "Management-Sensation-Selvhjælp" boghylde, der hvor Dilberts PHB får sin buzzword vide opdateret.

Koden bliver ikke bedre af at man køber en bog med en catchy titel og en smart forkortelse, koden bliver bedre af at man gør sig umage og tænker før man koder.

Poul-Henning

  • 0
  • 0
Nikolaj Brinch Jørgensen

Koden bliver ikke bedre af at man køber en bog med en catchy titel og en smart forkortelse, koden bliver bedre af at man gør sig umage og tænker før man koder.

Det er nemlig rigtigt! ;-)

@PHK

Jeg forstod ikke hvordan du er uenig i

Hmm, uenig. Dårlig kode tager tid.
Dårlig kode kræver konstant vedligeholdelse.

Altså dit svar

Nej, God kode tager tid og kræver mindst 2 forsøg.

Der er vel ingen forretningsidé i at bruge ekstra ressourcer på noget der ikke tilføre værdi? God kode er ikke i sig selv en værdi. Det skaber en værdi, da det er billigere, altså der er et lavere tidsforbrug forbundet med det.

  • 0
  • 0
Claus Jørgensen

Koden bliver ikke bedre af at man køber en bog med en catchy titel og en smart forkortelse, koden bliver bedre af at man gør sig umage og tænker før man koder.

Koden bliver bedre af at man lærer om koncepter og tankegange der udvider ens horisont nok til at kunne kode bedre.

Design Patterns af alle arter hjælper til dette (også GRASP). Derudover fungere de som et opslagsværk til at assistere med at finde det korrekte design. Udover at man altid bør have andre til at diskuttere og review problemstillingerne med.

Men netop at overvejer hvordan man pænest koder "responsibility" ind i sin arkitektur fører i sidste ende til pænere kode.

F.eks. at bruge annotations i de sprog der understøtter det, frem for at have if-checks i hver eneste metode, osv.

  • 0
  • 0
Claus Jørgensen

Nej, God kode tager tid og kræver mindst 2 forsøg.

God kode kræver forståelse, og til dels erfaring. Og altid erfaring i mere end et sprog.

Bare fordi man har kodet COBOL i 30 år, er man ikke nødvendigvis god til at kode python eller C#.

Netop forskellen mellem funktionelt og imperativt, og forskellen mellem proceduralt og objekt-orienteret, er vigtige for kvaliteten af ens kode.

At forsøge at kode COBOL som C# ville gå helt galt. Og det omvendte er også tilfældet.

Ligsom at forsøge at kode Haskell som C# heller ikke vil være særlig god kode (hvor det modsatte dog ikke er så slemt.)

  • 0
  • 0
Claus Jørgensen

Jeg stiftede bekendtskab med GRASP under min uddannelse. Senere hen har jeg læst 'Applying UML and Patterns' af Craig Larman.

Ah, så er det der jeg kender navnet fra.

Larman's bog var også en del af pensum på min uddannelse. Desværre blev der ikke brugt nok tid på at gennemgå koncepterne i dybden.

  • 0
  • 0
Carsten Sonne

Det lyder som titlen på en bog man ville finde i lufthavnens "Management-Sensation-Selvhjælp" boghylde, der hvor Dilberts PHB får sin buzzword vide opdateret.

Hehe, det kan du jo syntes. Det ændre dog ikke meget på indholdet.

Koden bliver ikke bedre af at man køber en bog med en catchy titel og en smart forkortelse, koden bliver bedre af at man gør sig umage og tænker før man koder.

Hvis vi alle skulle opfinde den dybe tallerken var menneskeheden nok næppe nået så lang. Jeg har noteret mig at du selv bruger andres indsigt og forståelse. Det er der så også andre der gør.

Jeg stiftede bekendtskab med GRASP under min uddannelse. Senere hen har jeg læst 'Applying UML and Patterns' af Craig Larman. Bogen er fra 1997.

  • 0
  • 0
Poul-Henning Kamp Blogger

Grunden til at jeg er skeptisk overfor "design patterns" og andre mode/buzz words, er at de alle forsøger at sælge en mere eller mindre forkromet genvej, der ikke findes.

Det sidste fornuftige ord i debatten blev langt hen ad vejen sagt i 1965 af Dijkstra i hans "Programming considered as a human activity" (http://userweb.cs.utexas.edu/users/EWD/transcriptions/EWD01xx/EWD117.html):

My own feelings are perhaps best described by saying that I am perfectly aware that there is no Royal Road to Mathematics, in other words, that I have only a very small head and must live with it[...]

I de 45 år der er gået, er hoveder ikke blevet større eller bedre end dem Dijkstra havde lejlighed til at observere og bruge.

Uanset hvilket buzzword man klistrer på, bliver de ikke større.

God kode kræver, mere end noget andet, en sådan ydmyg attitude til egen formåen og komplexitet, idet komplexiteten er selve problemets kerne:

Alle kan skrive god kode der er 10 linier lang, ingen kan skrive 1 mio linier god kode og de fleste strander allerede inden 2000 linier.

Da jeg startede, var det ikke usædvanligt at få smidt en 7cm tyk stak papir med et program på sit bord. Det virker utroligt befordrende på ydmygheden skal jeg hilse og sige.

Til reference ville en udskrift af FreeBSD kernen, uden userland, være 5m tyk, men takket være miljøhensyn bliver programmører ikke præsenteret for denne håndgribelige visualisering af opgavens størrelse.

I mine øjne har enhver der mener at have fundet lyset, hvad enten de kalder det SCRUM, GRASP, 4GL, eller blot wildcard'er med "Design Patterns," slet ikke forstået problemet til at begynde med og er derfor med meget stor sandsynlighed på vej væk fra at kunne producere god kode.

Jeg vil bestemt ikke afvise at man bliver en klogere og bedre programmør af at læse disse bøger, guderne skal vide at jeg selv har pløjet mig igennem mange i tidens løb.

Men man skriver ikke bedre kode ved at følge anvisningerne i en af dem mere eller mindre slavisk.

Eller som Frederick P. Brooks så klart udtrykte det:

There is no silver bullet

Først når man holder op med at lede, bliver ens kode bedre.

Poul-Henning

  • 0
  • 0
Jacob Christian Munch-Andersen

Hvis vi alle skulle opfinde den dybe tallerken var menneskeheden nok næppe nået så lang. Jeg har noteret mig at du selv bruger andres indsigt og forståelse. Det er der så også andre der gør.

Der er en ting som går igen igennem hele historien når vi snakker om udvikling, det er dem som tvivler på det bestående der skaber udvikling.

Til hver en tid er det bestående en blanding af sandheder, løgne, fejlfortolkninger, simplificeringer og uddateret viden.

For simple mennesker er denne blanding givetvis det bedste de kan få, men det er viden som det er umuligt at bygge videre på med mindre man kan skille skidt fra kanel, og det kan til tider betyde at man må starte helt forfra.

Det kan da være meget godt at få lidt inspiration til sådan noget som kode stil, men hvis ikke man går kritisk til det ender man let med blot at spilde tid på at gøre ligesom i bogen uden at ens kode bliver bedre. Hvilket dog langt fra altid afholder folk fra at tro at deres kode er bedre pga. ændringerne.

  • 0
  • 0
Claus Jørgensen

There is no silver bullet

Vi leder ikke efter den, men at have guidelines til opbygning af projekter der er for store til at en enkeltperson kan have det hele i hovedet, er yderst relevant.

Netop de gængse design patterns (Gamma et. al, 1995) udgør en mulighed for selvdokumenterede arkitektur (= selvdokumenterede kode), og dermed kan koden virke bedre og mere beskrivende end ellers.

Et af de mest hip koncepter i dag må jo klart være Inversion of Control / Dependency Injection [1], som på en måde bare er at genopfinde brugen af interfaces.

For mange giver det en fornuftig ide om hvordan man bør fokusere sin arkitektur/kode, direkte målrettet at skabe genbrugelighed og nemmere maintaince.

Man kan argumentere for at der intet nyt er i konceptet, og det er sådan set også rigtigt. Men forskellen er at det nu er dokumenteret, og kan bruges til forklaring, både til kollegaen, arkitekten og chefen.

Og det er nu engang hele formålet med design patterns. At skabe fælles forståelse. Ikke at opfinde en silver bullet.

Det samme gælder MVVM til Silverlight [2], som efter man har lært det, også lægger op til at bruge lign. koncepter i andre arkitekturformer hvor man arbejder med præsentation.

Og resultatet er (næsten) altid mere præcis og mindre rodet kode.

[1] http://martinfowler.com/articles/injection.html
[2] http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

  • 0
  • 0
Carsten Sonne

Det er ganske sandt at der ikke er nogen forkromet genvej, men der er en vej. Det er ligeledes sandt at der ikke er nogen silver bullet og giver det giver ingen mening at snakke om at se lyset. Det er først når et menneske begynder at bruge vendinger som at se lyset at det bliver problematisk. Det er nu ikke så specifikt for udvikling. Det samme gør sig gældende inden for religion, politik, alternativ behandling etc.

Patterns er intet andet end et slags værktøj. Det er blot nogle principper der kan anvendes på kendte problemstillinger.

På samme måde som man ikke kan lære at blive en god kok af at læse en bunke kogebøger og blot følge anvisningerne, kan man heller ikke blive en god programør af blot at følge anvisninger i en bog om design patterns.

Derimod kan design patterns hjælpe til at få styr på nogle erfaringer ved at forsøge at klassificere dem samtidig med de kan hjælpe til at gøre de næste erfaringer lidt mindre smertefulde.

Det er meget typisk at design patterns ikke kan læres uden at have en vis erfaring med de problemstillinger det enkelte pattern forsøger at generalisere. Det giver først rigtig stor værdi efter en del bitre erfaringer. Hver gang man læser om et pattern forstår man det bedre og bedre.

Det hjælper ikke at lede, men det hjælper at reflektere. Hvis ens refleksioner kan støttes af andres erfaring, er det blot en styrke.

  • 0
  • 0
Poul-Henning Kamp Blogger

Det er meget typisk at design patterns ikke kan læres uden at have en vis erfaring med de problemstillinger det enkelte pattern forsøger at generalisere.

Og dermed er vi tilbage til det første jeg skrev in denne thread:

PS: Det tager omkring 15-20 år at lære at skrive god kode.

Kodning er et håndværk og en kunst: øvelse gør mester.

Poul-Henning

  • 0
  • 0
Therese Hansen

Nu kan jeg ikke lige huske hvilken af Malcolm Gladwells bøger det er, han nævner at det tager ca. 10.000 timers øvelse at blive rigtig god til noget (måske er det Outliers). Hvad end det så er klaverspil eller kode, så spiller talent kun en mindre rolle - det er timerne man har lagt i det, som er afgørende. Det er dog mere sandsynligt at man lægger mange timer i noget som man har talent for.

Jeg vil så tilføje at man (som tidligere nævnt i denne tråd) også skal stræbe efter at blive bedre og reflektere over sin kode før der sker forbedringer.

  • 0
  • 0
Kent Damgaard

Den amerikanske tegneserie-forfatter Kurt Busiek citerer ... tror det er John D. McDonald for at sige tilsvarende at enhver forfatter har 100.000 dårlige ord i sig som det gælder om at få ud af kroppen så man kan begynde at skrive gode historier. Min tegnende kollega på den anden side af gangen har et tilsvarende citat om det at tegne.

Jeg tror at det hænger sammen med at det kun er ved at gøre tingene at man ser hvad der ikke virker eller er alt for besværligt at gøre så man begynder at korrigere.

  • 0
  • 0
Nikolaj Brinch Jørgensen

Nu kan jeg ikke lige huske hvilken af Malcolm Gladwells bøger det er, han nævner at det tager ca. 10.000 timers øvelse at blive rigtig god til noget (måske er det Outliers). Hvad end det så er klaverspil eller kode, så spiller talent kun en mindre rolle - det er timerne man har lagt i det, som er afgørende. Det er dog mere sandsynligt at man lægger mange timer i noget som man har talent for.

Det er da en interessant teori. Jeg vil erklære mig uenig - eller sagt på en anden måde
Michael Laudrup og Stig Tøfting har nok trænet sådan ca. lige meget (muligvis har Tøffe faktisk trænet mere), men skal vi bare sige talent betyder en del ;-)

  • 0
  • 0
Daniel Madsen

Michael Laudrup og Stig Tøfting har nok trænet sådan ca. lige meget (muligvis har Tøffe faktisk trænet mere), men skal vi bare sige talent betyder en del ;-)

Der er nok ingen tvivl om at blandingen af talent og erfaring giver det bedste resultat. Hvorvidt Stig Tøfting havde talent eller ej vil jeg ikke blande mig i, men hvis han definerer en talentløs fodboldspiller så holder tesen dog alligevel nogenlunde stik - han formåede trodsalt at have en karriere som professionel fodboldspiller (endda på landsholdet) ved at træne hårdt nok for det.

  • 0
  • 0
Nikolaj Brinch Jørgensen

Der er nok ingen tvivl om at blandingen af talent og erfaring giver det bedste resultat. Hvorvidt Stig Tøfting havde talent eller ej vil jeg ikke blande mig i, men hvis han definerer en talentløs fodboldspiller så holder tesen dog alligevel nogenlunde stik - han formåede trodsalt at have en karriere som professionel fodboldspiller (endda på landsholdet) ved at træne hårdt nok for det.

Jeg er ikke sikker på Tøfting var talentløs - eller definere den talentløse. men mere måske spilleren med mindst talent.

Der var jo milevid forskel på dem som spillere.

Til det kan man sige, at der findes mange professionelle som ikke gør deres arbejde særlig godt. Eller der er i hvert fald nogle som bare gør det en del meget bedre. Det gælder alle håndværkere - også IT professionelle. Om de har personlig success - altså et arbejde - er vel ingen indikation på noget som helst.
Tøfting spillede f.eks. ikke ik Barcelona, Juventus eller nogle af de klubber som en talentfuld spiller kan spille i.

Men jeg tror da at hr. Gladwells bog passer meget godt ind i Jante-Danmark, hvor det er bedst hvis vi udgør en grå masse og er hulens konfliktsky.

Der er bare folk der har mere talent end andre, også for programmering. Lige gyldigt hvor meget man træner når man dem aldrig - sådan er det, og sådan vil det altid være.

  • 0
  • 0
Nikolaj Brinch Jørgensen

Det er bare så trist, hvis det eneste man kan stræbe efter, er at blive gammel

Ja det har du ret i. Der kræves dog erfaring. Nogle kan så få den erfaring på kortere tid end andre. 15-20 år er vel hvad PHK har brugt på at blive god til det, efter sin egen mening.

Det der er problemet, er hvis man benytter mål for sig selv på andre.

  • 0
  • 0
Log ind eller Opret konto for at kommentere
IT Company Rank
maximize minimize