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 :)

Tuesday, February 9, 2010

Don't Swallow Exceptions - Ever!

Among lots and lots of good reason not to swallow exceptions, I just ran into a doozy. I'm rewriting a VB.Net application in Java. It has some really complex calculations. One of the calculations involves using a 2D array to setup some default values. The array is in a try catch block. With a catch(Exception e) and nothing else. No logging. Nothing.

Two days of trying to figure out why my calculations are slightly off what's expected. Thank you FitNesse, by the way. Anyway, come to realize that I'm swallowing an IndexOutOfBoundsException. See, VB.Net starts arrays at 1 while Java starts arrays at 0, so my array initialization was barfing and returning a bad value.

I did what most of us do now and then. I saw the empty catch block and thought, "I'll get back to that. I just want to get these calculations right. Then I'll fix those exceptions." Woops.

Handle exceptions as soon as you write the catch block. Handle it as best you can. At the very least print it to standard error, so when it happens you know it happened. Had I done at least that, I wouldn't be two more days behind.

Thursday, January 21, 2010

XP is Not a Set of Practices

A recent discussion on the XP Yahoo! group has gotten me thinking about Extreme Programming and Agile Software Development in general. The discussion is around to test or not to test. Kent Beck's blog post provides an over all look into his view at To Test or Not To Test

The discussion started with someone asking for XP Myths and to test or not to test popped up and hijacked the thread. If you are really interested in the gory details of the thread, see http://tinyurl.com/yes8b2u for details. The discussion then stemmed into something like, "well, if it's OK to not test when you are exploring what people will pay for, it might be OK to not do XP". But what does "not do XP" mean?

That got me thinking about "Lean Thinking" by Womak and Jones because I've never looked at XP as a set of practices, well, I did early on but grew out of it. I look at XP and any Agile methodology as a system with certain core values and principles. I prefer to build my XP process based on the same principles expressed in "Lean Thinking:" value, value stream, flow, and perfection. If you want a more detailed list of principles on which to base your agile methodology, see "Lean Software Development" which has, if I recall correctly, 7.

Value

From a lean perspective, value is what you sell to make money. In software that means, well, software. It's why the customer pays you. The customer pays you because the software saves or makes her money. So the main principle is everything you do in your process must create value or it's muda or 'waste'. Whenever you decide to implement a practice ask yourself, "Will this practice help the team create value?" Alternately, whenever you decide to skip a practice, ask yourself, "How will skipping this practice affect the teams ability to create value?"

Value Stream

The value stream is the entire production process. Often it is helpful to map your value stream to see how the value gets produced. In manufacturing it could start at the mine where the raw materials are extracted from the Earth and end where the shiny new product rolls off the assembly line.

In software, your value stream could start with the customer asking for a new feature and flow all the way to delivery back to the customer. To map your value stream, write down every step the team takes while delivering that new feature. Once you have a complete value stream map, you can start looking for muda. Things you do that do not directly contribute to the creation of the desired feature - the value. Also look at all activities the team does that are not in the value stream map. Those activities are primary muda. Secondary muda are activities that contribute in a secondary way but do not directly produce value. An example of secondary muda is source control activities. Using a source control system is a vital component to software development. It keeps track of file changes, enables sharing of code, and allows branching for tracking software versions. All key to developing good software, but none add directly to the value. In other words, a customer will not pay you more money whether you use an SCM or not. In secondary muda cases, the goal is to minimize the time and effort spent on the activity. If the team spends 2 hours a day mucking about with SCM activities, find out why and reduce that time, so the team can spend more time on valuable activities.

Flow

The current buzzword of the agile industry. In manufacturing, flow is how well the value moves through the value stream. It addresses things like inventory and production backlog. For example, if a certain station on the assembly line always has a huge inventory of product stacked up in front of it, and the station down line is always waiting, then there is a flow issue. This is where the Toyota Production System concept of pull comes in to play. Traditional assembly lines thought the plant was most efficient when run at full capacity, but that often produces flow problems. Pull allows each station to pull product from the previous station, so each station can work at its full capacity. Less waste.

The current Kanban movement in software development is based on the concepts of flow and pull. The swimlanes on a Kanban board often map to the value stream map with each swimlane able to pull from the previous swimlane. All of your activities should allow the value to flow through the value stream. Once you have your value stream map, you analyze how the value flows through the system and address bottlenecks.

Perfection

Perfection addresses how the Toyota Production System constantly strove to improve itself. Kaizen is the constant little improvements each team tries to do everyday thinking that small continuous improvements eventually add up to big gains in effectiveness.

In software, retrospectives are often used to identify and address any issues that came up during the previous iteration or sprint. Encourage your team to constantly identify any issues with flow. As the team gets better and better, different problems pop up. Perhaps the team as become very proficient with the new technology and is producing faster than test can verify. Certainly a good problem to have, but a flow problem none the less. According to Theory of Constraints thinking, you move the constraining part ahead of the part that's overwhelming it. Moving test ahead of development, writing automated tests that are executed as the release criteria, now frees test from getting swamped and sets valuable limits on development.

Conclusion

I'm not willing to say what XP is, but I am willing to say it is not just a set of practices. I do believe the best methodologies are built from principles and values and not from a list of practices which are dogmatically executed day in and day out. Each practice you decide to adopt, be it a traditional XP practice, one from another methodology, or one the team creates itself, should contribute to value, value stream, flow, or perfection. Only then will you know it is worth trying. When evaluating whether to dump or skip a practice, analyze how that practice contributes to value, value stream, flow, or perfection to determine the affect dropping the practice will have.