Monday, December 10, 2012

Riktlinjer för Kodgranskning aka Code Review


Det är svårt att granska kod. Men nödvändigt om man vill ha en långsiktigt underhållsbar kod. Jag tror att det är precis detta man ska tänka på när man granskar kod: kommer denna kod vara lätt att utöka, ändra på och felsöka, etc.

Jag har inte bestämt mig om parprogrammering eller kodgranskning är bäst. Båda tillsammans är naturligtvis bäst, men antagligen inte tidseffektivt. Om man har svårt att få till kodgranskningen i sin grupp bör man nog gå över till parprogrammering. Det är ju kontinuerlig kodgranskning, och kontinuerliga aktiviteter är ju trenden inom mjukvaruutveckling.

Här är i alla fall några områden som jag tycker man bör titta på. Denna lista kan bli hur lång som helst, men jag tror det är bättre att fokusera på ett fåtal viktiga saker Att koden fungerar för det huvudsakliga användningsfallet kollar inte jag. Det får man ta för givet. Annars har man problem som inte den bästa kodgranskning kan lösa.


  1. Implementation matchar dokumentation
  2. Klass & metod access - så strikt som möjlig
  3. Felhantering
  4. Exceptions
  5. Loggning
  6. Gränsvärdesvillkor (tex tom lista)
  7. Om equals överrids, då måste hashCode överridas (och vice versa)
  8. Tester: enhets och komponent och/eller integration om tillämpligt
  9. Storlek på klasser & metoder
  10. DRY - Don't Repeat Yourself


Implementation matchar dokumentation

Bättre ingen dokumentation än felaktig eller missvisande dokumentation.

Klass & metod access - så strikt som möjlig

Många verkar knappt känna till, än mindre använda default scope, aka package-private. Detta är det rätta scopet för implementationsmetoder och även klasser som inte kan vara privata men som inte bör läcka ut.

Felhantering

Programmeraren tänker ofta på fallet när allt går bra. Och ofta är felhanteringen ospecad. Men vad händer t.ex. om man får ett oväntat svar från ett annat system? Hanter koden det? Loggar den? Stängs resurser?

Exceptions

Exceptions är kraftfulla rätt använt. De ger möjlighet till alternativ returpunkt och returtyp från en metod. Betänkt att det är en icke-lokal GOTO, och kan därmed göra det mer komplicerat. Många verkar skygga eller okunniga för att skapa egna Exception klasser. Gör gärna det. Med trevliga bekväma konstruktorer. Behöver inte bara vara String message och Throwable e utan kan innehålla mer data om felet som kan exponeras i en getter för klienter längre ner i call stacken.

Loggning

Lagom mycket, vid rätt tillfälle och på rätt nivå. Skriv gärna en hjälpmetod för loggning om du loggar liknande saker vid flera tillfällen. En toString() på klasser av värde typ minskar mängden kod för att logga enormt:
log.info("Did something with: " + this);

Och begå inte dödssynden, svälja ett exception stacktrace i din loggning:

catch(SomeException e) {
    log.warn("something happend");
}
Så här ska det vara:

catch(SomeException e) {
    log.warn("something happend", e);
}
Om det är värt att logga överhuvudtaget, så är det värt att logga även stacktracet.

Gränsvärdesvillkor (tex tom lista)

Hanterar koden null, tomma listor och andra gränsvärden på ett bra sätt. Kasta hellre IllegalArgumentException istället för att tyst svälja nåt som blir ett svårdebuggat problem långt senare i exekveringen.

Om equals överrids, då måste hashCode överridas (och vice versa)

Annars kan det bli jobbigt. Tro mig. Använd gärna automatgenerering i IDE:t. Då får man båda på en gång och konsistens till på köpet.

Tester: enhets och komponent och/eller integration om tillämpligt

Det finns väl tester för koden? Ju mer komplicerad kod, desto mer enhetstester. Tester fångar ofta fel som man aldrig tänkt på. Bättre med ett idiottest som "aldrig kan faila" än inga tester alls.

Storlek på klasser & metoder

Detta bör visserligen fångas i CI av ett verktyg för automatisk statisk kodanalys. Men ibland är långt under max-värdet det lämpliga.

DRY - Don't Repeat Yourself

Den underliggande principen för det mesta!

Tuesday, August 07, 2012

My favorite programming books

Here is a list of my favorite programming books. The top five I consider essential reading for any serious java developer.
  1. The Pragmatic Programmer - From Journeyman to Master, 1999 (Andrew Hunt, David Thomas)
    • Essential for the aspiring programmer. Some sections are still an unattainable ideal to me, but they all make sense and I am getting closer to that ideal day by day, inch by inch. The book explains important concepts such as orthogonality.
  2. The Mythical Man Month - Essays on software engineering, 1975 (Frederick Brooks)
    • It's now 37 year since this book was published, but it's still very relevant and definitely worthwhile reading. These essays coined many of the terms and ideas that are still heavily used today in software engineering.
  3. Design Patterns - Elements of Reusable Object-Oriented Software, 1995 (Erich Gamma)
    • I don't think this book need any comment. It's a must read.
  4. Refactoring - Improving the Design of Existing Code, 1999 (Martin Fowler, Kent Beck)
    • Same goes for this one as the one above.
  5. Effective Java 2nd ed, 2008 (Joshua Bloch)
    • Great, well written book for the Java developer. It can be read from cover to cover, but is also a reference for all the basic things in Java. For example almost manages to make threading and concurrency fun, at least interesting and understandable.
  6. Domain-Driven Design - Tackling Complexity in the Heart of Software, 2004 (Eric Evans)
    • Every now and then one starts to get a feeling that everything essential has been said about a subject, in this case software design, and then a book comes out that manages to renew the field. This is one of those books. One great idea from this book is that of the ubiquitous language. A summary of this book is available as a InfoQ mini-book
  7. Test Driven - TDD and Acceptance TDD for Java Developers, 2007 (Lasse Koskela)
    • This book managed to completely convince me of always using TDD for all future. It's a very nice combination of theory and practice and it uses some well-known frameworks and standards as example to show that most things can be tested and TDD:d. The only objection I have is that as things sometimes move very quickly in our business; especially within ATDD there has been a lot of effort recently, so this section does not cover the latest and greatest tools and ideas. But it's still good as an introduction to and a sell for ATDD.