Thursday, February 18, 2010

Code Katas I'd Like to See More Of

If you haven't heard of code katas, then you should really check them out. Like their namesake in Karate, code katas are little pieces of code you write over and over to exercise your coding muscles. And as opposed to bench pressing to exercise your coding muscles, katas are designed to fine tune not just strengthen.

I'm not sure who coined the term or idea, but I tend to get most of my katas from Dave Thomas at http://codekata.pragprog.com/

I like the katas listed there, but my experience is that they are mostly just programming contest problems designed to exercise your problem solving skills. That's a good thing, by the way, but there are more than just problem solving skills to master on the road to becoming a software craftsman.

What I'd like to see is more katas like:

Given the follow class:

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

import junit.framework.TestCase;


public class PolyKata extends TestCase {
 private PrintStream stream;
 enum shape {square, triangle, rectangle}
 
 private void drawPoly(shape the_shape) {
  switch (the_shape) {
   case square:
    stream.print(shape.square);
    break;
   case triangle:
    stream.print(shape.triangle);
    break;
   case rectangle:
    stream.print(shape.rectangle);
    break;
  }
 }
 
 public void test_drawPoly_square() throws Exception {
  PrintStreamFake stream_fake = new PrintStreamFake(shape.square);
  stream = stream_fake;
  drawPoly(shape.square);
 }
 
 public void test_drawPoly_triangle() throws Exception {
  PrintStreamFake stream_fake = new PrintStreamFake(shape.triangle);
  stream = stream_fake;
  drawPoly(shape.triangle);
 }
 
 public void test_drawPoly_rectangle() throws Exception {
  PrintStreamFake stream_fake = new PrintStreamFake(shape.rectangle);
  stream = stream_fake;
  drawPoly(shape.rectangle);
 }
 
 private static final class PrintStreamFake extends PrintStream {

  private shape the_shape;

  public PrintStreamFake(shape theShape) throws IOException {
   super(File.createTempFile("temp", "file"));
   this.the_shape = theShape;
  }
  
  @Override
  public void print(Object obj) {
   assertEquals(obj, the_shape);
  }
  
 }
}


Refactor using "replace conditional with polymorphism". Do this kata five days in a row, refactoring to a different design pattern each time. Then do it one more time only this time focus on taking the smallest steps possible and still keep the tests green. Also find ways to clean up the test code, as there's some duplication that can go as well.

To become a craftsman, you must refine your problem solving and coding skills, but you must also refine your code nose and refactoring skills. You must learn to quickly identify the stench of crap code and perfect your refactoring skills so you can quickly, cleanly, and efficiently replace crap code with clean code.

This is a perfect task for code katas. I only hope more of these come into play. I'll try to contribute my fair share, and if there are katas of this ilk out there in the tubes of the Internets already, please don't hesitate to point them out in the comments.

And I have to add, I had to look up how to do enums and switch statements in Java. That's how much I use them :)

No comments: