How to drive code by sketching it

Actually, there are numerous of ways to sketch software or pieces of it. Drawing with a pen on a paper or on a white-board, using an UML tool et cetera. The goal is just to get things simplified and get an abstract view of it to find the core issues. With the introduction of Test-driven Development (TDD) a new way appeared end of the 90ties. TDD is controversially discussed and I don’t want to dig into the pros and cons of this approach. Rather I’d like to pick up one aspect of this methodology: drive code and design by coding.

Testing a class means to think about the usage of it, thus to think about interfaces.
The interfaces must not be final during sketching respectively coding the first draft. It is possible to re-factorize the code with less effort – even continuously until the sketch emerged into something which seems to be decent at that time. It’s more like outlining a first simple idea and to sketch the design by coding. So no waste of paper, ink and time. My intention is not to abandon every diagram. Depending of the size and complexity of the software its architecture and components should be described via diagrams and a few words.
But by using a few buddies you can literally play with the code. It’s no waste of time to create more than one sketch, modifying the sketch until it fits and even throw a peace away to start from the scratch again. Doing this with an ordinary text-editor would be pain, but with a sophisticated IDE it could be fun and productive.

The sketch buddies

Treat an

  • IDE like eclipse
  • the compiler and
  • an ordinary unit-test class

as your buddies.
Note: This article relies on short-cuts and the Quickfix feature of eclipse. If you don’t use eclipse, similar features could exist in your IDE but could have other names. If you like, open your IDE, create a java-project containing the junit library and follow the items step by step.

The idea is not to think about how to write code the compiler likes rather than writing code the compiler does not like, but the IDE knows how to satisfy the compiler. I.e. if the requirement is, to create a feature and a code-snippet that can print something, don’t type java-code like:

public class Printer{
   ...
   public void print(String text){
     ...
   }
}

Instead write into a common test-method of a unit-test class something like:

@Test
public void testSketch(){
    myPrinter.print("a text");
}

and the compiler will complain that myPrinter is not specified yet. You just wrote how to use your Printer and you didn’t wasted any time to think about language details and how the syntax should look like of the class and method body. You only have to think about the syntax how to use the feature resp. how to call the method. Even if your are used to the programming-language, typing class bodies and method signatures is waste of time with an IDE like eclipse.

Sketchpad Pong

Now, just place the cursor on the red underlined text the compiler complains about in your IDE and hit CTRL + 1 (Quick Fix). A small inline-menu pops up and if you are lucky shows one or more possible solutions.
Creating a local variable myPrinter is obvious in this case and is suggested by the IDE. Select that suggestion and a new line is created above your initial code like:

Object myPrinter;
myPrinter.print("a text");

In this case you have to change the type Object into something else of course. Do not think about the name just spontaneously type a class name e.g. like Printer and hit Enter.
Assuming the class Printer does not exist the compiler complains about it and what’s next? Yes, mark the red part and hit CTRL + 1. One of the shown items suggests to create a new class. And the idea is to create a new one, but as an inner class in the test-class – your sketchpad.
Select Create class Printer and a GUI pops up which asks you to create a new class. In that GUI you can select Enclosing type. Confirm and a new inner class Printer has been created.
And next? The compiler complains about the missing method print(…). Yes, mark the red part hit CTRL + 1 select Create method print(… and the method is created in the empty class body. Give the method-parameter spontaneously a name and hit Enter.
Almost done. The variable printer has to be initialized of course. The IDE suggests to use a null value but just initialize it via an default constructor in this case like:

Printer myPrinter = new Printer();
myPrinter.print("a text");

PongNow the compiler should be satisfied. Your sketchpad contains an example how to use the feature, the class and method body – just with a few clicks without syntax, formating etc. issues. Your cursor jumps between test-code and production-code on your sketchpad; like the ball in the game Pong

public class SketchTest {
    public class Printer {
        ...
        public void print(String text) {
        // TODO Auto-generated method stub
        }
    }

    @Test
    public void testSketch(){
        Printer myPrinter = new Printer();
        myPrinter.print("a text");
    }
}

Sketch – don’t worry about decisions

Usually in TDD a next step could be to add the first Assert to define the wanted behavior of the method. However let’s introduce some difficulty: we need to call an external class which does the print job using an external system. I.e. we have to deal with an API of an external system in the new class Printer.
One approach could be to create a constructor or using a setter to initialize a member-variable containing the external stuff. In this case we decide to go for the constructor. Don’t worry about any decision. Everything could change, we are just sketching ideas. If we find out later the choice does not fit, it’s easily changeable in this early stage.
What’s next? Correct, do not type the constructor into the inner class Printer. Modify the constructor call like:

Printer myPrinter = new Printer(new AnExtPrinter());

And now your buddy complains again that he does not know AnExtPrinter. I guess you know how to create it? Yes, create it as an inner class of the test via CTRL + 1. Unfortunately now the class Printer has its first nasty dependency. To keep this class with less dependencies we should go further with interfaces on signatures. I.e. select the class AnExtPrinter open the context-menu and choose Refactor–>Extract interface …, type an interface name like ExtPrinter into the popped up GUI and confirm. Your code looks like:

public class SketchTest {

	public class AnExtPrinter implements ExtPrinter {

	}

	public class Printer {

		public Printer(ExtPrinter anExtPrinter) {
			// TODO Auto-generated constructor stub
		}

		public void print(String text) {
			// TODO Auto-generated method stub
		}

	}

	@Test
	public void test() {
		Printer myPrinter = new Printer(new AnExtPrinter());
		myPrinter.print("a text");
	}

}

And a new interface ExtPrinter has been created in a new file ExtPrinter.java containing code like:

public interface ExtPrinter {

}

As you might have notice the constructor-signature of the class Printer does not use the class AnExtPrinter any longer, it uses the interface ExtPrinter instead. Quite nice, no dependency on external stuff until now. Without thinking about it or forgetting the type-change in the constructor-signature.
Additionally we didn’t spend much time on finding reasonable names yet. The naming will follow if the real core purpose of the class or method is clear, because it could change via re-factorization steps quite often – which is part of the sketching.
Go further with this example in the next part: Sketching around external APIs