Alexandre Martins On Agile Software Development

26Jul/103

TDD: Listen to the tests… they tell smells in your code!

These days, reading the Goos book, by Steve Freeman and Nat Pryce, it reminded me of a project I worked on a while ago. It was a one year old system, poorly tested, integrating to a handful of other systems, and the code-base... well I prefer not to remember. Despite this scenario, I joined the team to help them implement some new functionalities.

I remember sometimes it was difficult to write tests, the classes were tightly coupled, with no clear responsibilities, several attributes, bloated constructors, etc. And despite our best effort, working around the bits that were preventing us from writing the tests, we felt we were getting down the wrong road, trying to do it in such a crappy code-base. As a result some of our tests were massive! A bunch of lines of mocks, stubs, and expectations, making it impossible to understand their purpose.

What have I learned?

Reading one of the book chapters I learned that the same qualities that makes an object easy to test also makes the code responsive to change. In my situation, the tests were telling me how clumsy the code was and how difficult it would be to extend it.

I also learned that when we come across a functionality that is difficult to test, asking ourselves how to test it is not enough, we also have to ask why is it difficult to test, and check whether it's an opportunity to improve our code. The trick is to do it driven by tests, so we can get rapid feedback on code's internal qualities and on whether it's doing what it's supposed to do.

So they introduced a variation for the well-known TDD cycle— "Write a failing test" => "Make the test pass" => "Refactor". As described on the figure below (extracted from the book), if we're finding it hard to write the next failing test for our application, we should look again at the design of the production code and often refactor it before moving on, until we get to the point that we can write tests that reads well.

Extracted from Growing Object-Oriented Software, Guided By Tests— Steve Freeman and Nat Pryce

An Example of a Smell Tests Might Be Telling You

Reference data rather than behavior

When applying "Tell Don't Ask" or "Law of Demeter" consistently, we end up with a coding style where we tend to pass behavior into the system instead of pulling values up through the stack. So picking up the famous Paperboy example, before refactoring the code applying the "Law of Demeter" the code and test would look something along the lines of the snippet showed below.

class Paperboy
  def collect_money(customer, due_amount)
    if due_amount > customer.wallet.cash
      raise InsuficientFundsError
    else
      customer.wallet.cash -= due_amount
      @total_collected += due_amount
    end
  end
end
it "should collect money from customer" do
  customer = Customer.new :wallet => Wallet.new(:amount => 200)
  paperboy = Paperboy.new
  paperboy.total_collected.should == 0
  paperboy.collect_money(customer, 50)
  customer.wallet.cash.should == 150
  paperboy.total_collected.should == 50
end

We can easily see that the test is telling us it knows too much detail about Customer class implementation. We can see its internals, which objects it's related to, and even worse, we're also exposing implementation details of its peers. So it's clear for me that it needs some design improvement. My main goal here is to hide Customer implementation details from the users of the Paperboy class. Which means that I don't wanna see anything but Customer and Money classes referenced on the test!

class Paperboy
  def collect_money(customer, due_amount)
    @collected_amount += customer.pay(due_amount)
  end
end
it "should collect money from customer" do
  customer = Customer.new :total_cash => 200
  paperboy = Paperboy.new
  paperboy.total_collected.should == 0
  paperboy.collect_money(customer, 50)
  customer.total_cash.should == 150
  paperboy.total_collected.should == 50
end

The method customer.pay(due_amount) wraps all the implementation detail up behind a single call. The client of paperboy no longer needs to know anything about the types in the chain. We've reduced the risk that a design change might cause ripples in remote parts of the codebase.

As well as hiding information, there's a more subtle benefit from "Tell, Don't Ask." It forces us to make explicit and so name the interactions between objects, rather than leaving them implicit in the chain of getters. The shorter version above is much clearer about what it's for, not just how it happens to be implemented.

All the logic necessary to collect the money is inside the Customer object, so it doesn't have to expose its state to its peers.

Now it's safer to continue writing new failing tests to our objects.
Remember, listen to the tests!

1Jan/093

Clojure: Integrating With Java

Currently I am learning Clojure. It is a functional programming language, but not a pure one, since you can both write code that share state (mutable) and also ones that doesn't.

Why Clojure?

The main reason why I chose Clojure is its easy interoperability with Java, still one of the most used languages, bringing to it the power of Lisp. It's fast, since the code is compiled, and it supplements some of Java's weakness, such as the Collections framework and concurrent programming. It is pretty straightforward to write concurrent programs, everything is automatic, no manual lock management!

Integrating With Java

Importing classes

A single class:

(import java.util.List)

Multiple classes from the same package:

(import '(java.util List Set))

Creating instances

Using Java's new keyword:

(new java.util.ArrayList)
(new ArrayList) ; after importing

Assigning a new List to a Clojure variable:

(def list (new java.util.List))
-> #'user/list

Syntactic Sugar:

(ArrayList.)

Accessing fields

Static fields:

(. Math PI)

Syntactic Sugar:

Math/PI

Invoking methods

Static Methods

(.currentTimeMillis System)

Syntactic Sugar:

(System/currentTimeMillis)

Non-static Methods

(. list size)
(. list get 0) ; returns the object stored at index 0

Syntactic Sugar:

(.size list)

Mixing Them All

Clojure provides a macro called memfn that makes possible execute Java methods as functions. So, for a list of String objects, if I want to make all of them upper-case, all I have to do is:

(map (memfn toUpperCase) ["a" "short" "message"])

The map function applies the function/method toUpperCase to each element in ["a" "short" "message"]

You can also use the bean function to wrap a Java bean in an immutable Clojure map.

(bean (new Person "Alexandre" "Martins"))
-> {:firstName "Alexandre", :lastName "Martins"}

Once converted, you can manipulate the new map using any of Clojure’s map functions, like:

(:firstName (bean (new Person "Alexandre" "Martins")))
-> Alexandre

The code above extracts the firstName key, originally from the Person object.

6Nov/080

First Sydney Coding Dojo

Last Wednesday, 5th of November, we run our first Coding Dojo session at Sydney office. We had a reasonable number of attendants, and the experience was fantastic, although we still have some points to improve.

The Initiative

The idea was originally from my friend and flat-mate Mark Needham. Since we moved in to our new place, he came up with the idea of getting together every week to solve some CodeKatas at home, exploring a different language. We decided it would be more interesting if we could broaden the idea, and decided to organise a session at the Community College in the ThoughtWorks office.

How did we run:

There were six people attending, so we decided to split it into three pairs, each with their own solution, rotating every ten minutes.
We had three design discussion breaks, one in the beginning, one in the middle and another at the end of the session. Since the focus was on object-oriented design, we chose to implement the bowling game, extracted from Uncle Bob Martin's book. We did it following the Object Calisthenics rules, which are:

  • Use only one level of indentation per method
  • Don't use the else keyword
  • Wrap all primitives and strings (strong types)
  • Use only one dot per line
  • Don't abbreviate
  • Keep all entities small
  • Don't use any classes with more than two instance variables
  • Use first-class collections
  • Don't use any getters/setters/properties

What was cool:

Apart from being an amusing experience, it was quite interesting to see the different approaches that people take to solve the same problem, - the design, the way they write tests, the code style, pretty cool. The pair swapping was also another nice experience. It was gratifying to pair with ThoughtWorkers other than the ones on my current project, like David Cameron and Nick Carroll.

Future improvements:

For the next session, I would like to experiment with another approach.
Restrict the number participants from seven to ten developers. And instead of splitting them into as many pairs as possible, having all seated around a table, where there would be only one pair working on the solution, while the others are watching through a projector. They are free to help whenever they want, providing suggestions, ideas for design, algorithm, etc. The developers pairing would be swapped every ten minutes, by other ones participating. Although the number of developers participating is restricted, anyone is welcome to attend as a watcher.

I reckon we would be much more productive this way, when everyone is working on the same thing, centralizing the focus, and learning even more from other developers.

15Apr/080

Benefits of supporting tools

One of the deliverables to our current client is a project template, containing tools to guide them to build better software, ensuring lower bug occurrence and system integrity.
One tool we are using is Findbugs. One day, when running it, we came across an interesting issue, Findbugs was complaining that a class in a project was exposing its internal state, subjecting it to unexpected modifications. The class contained a single constructor with parameters setting its initial state and a set of getter methods. Any Java developer used to getters and setters pattern would say that the code below is valid.

public class Person {

	private String name;
	private Date dateOfBirth;

	public Person(String name, Date dateOfBirth) {
		this.name = name;
		this.dateOfBirth = dateOfBirth;
	}

	public Date getDateOfBirth() {
		return dateOfBirth;
	}
	public String getName() {
		return name;
	}
}

What would happen if you create a Person instance passing as parameter, pre-defined name and dateOfBirth variables and then, perform operations over these variables, modifying its states? And what if you retrieve these attributes (through getter methods), assigning them to new variables and start performing operations over them? For the name attribute it wouldn't be a problem, since String objects are immutable, but certainly both cases would affect the dateOfBirth attribute, corrupting the state of the object.

One of the solutions to this problem would be to make getter methods always return a new object, copy of the original one and during object construction, initialize instance variables with new objects, copy from the original ones passed as constructor parameters.

public class Person {
	...

	public Person(String name, Date dateOfBirth) {
		this.name = name;
		this.dateOfBirth = new Date(dateOfBirth.getTime());
	}

	public Date getDateOfBirth() {
		return new Date(dateOfBirth.getTime());
	}
	...
}

So, unless the objects you are implementing are good citizens and contains side-effect-free functions, you should consider programming in a more defensive way, to avoid unexpected behaviors in your project and also make use of tools like Findbugs to turn the development easier. Checkstyle and Cobertura are a good start.

4Jul/070

JBehave Matchers

JBehave and JMock2 are tools I've been using on my latest projects to define the behaviours of my objects. Both, when used together supplies pretty much all the resources needed to write effective behaviour verification. But in this topic I'm going to talk about JBehave Matchers.

Matchers are handy objects, inspired by JUnit Assert class, but much more elaborated. They can help us in loads of scenarios, without the need to write repeated code, such as loops, ifs, elses, turning out the code cleaner and much more intuitive. Currently there are six matcher subtypes: UsingArrayMatchers, UsingCollectionMatchers, UsingEqualityMatchers, UsingExceptions, UsingLogicalMatchers e UsingStringMatchers. For now, I'm just going to talk about four of them, which for me are the most innovative ones.

UsingArrayMatchers e UsingCollectionMatchers

Both are quite similar in their behaviours, the only thing that distinguishes them, as their names indicates, is the object on which operations are executed upon. I decided using the UsingArrayMatchers matcher to show some examples of features it comprises:

1 - Check if a Collection/Array contains a certain object:

Integer[] array = new Integer[] {3};
Ensure.that(array, contains(3));
Ensure.that(array, not(contains(5)c));

2 - Check if a Collection/Array contains a certain set of objects:

Integer[] array = new Integer[] {3, 4, 5};
Ensure.that(array, contains(3, 4));
Ensure.that(array, contains(3, 4, 5));

3 - Check if a Collection/Array contains only a certain set of objects, and nothing more:

Integer[] array = new Integer[] {3, 4, 5};
Ensure.that(array, containsOnly(3, 4, 5));
Ensure.that(array, not(containsOnly(3, 4)));

4 - Check if a Collection/Array contains a certain set of objects, in a defined order:

Integer[] array = new Integer[] {3, 4, 5};
Ensure.that(array, containsInOrder(3, 4, 5));
Ensure.that(array, not(containsInOrder(4, 5, 3)));

UsingStringMatchers

The methods in this class are self-explanatory, just check it out:

Ensure.that("octopus", contains("top"));
Ensure.that("octopus", not(contains("pee")));
Ensure.that("octopus", startsWith("octo"));
Ensure.that("octopus", not(startsWith("pee")));
Ensure.that("octopus", endsWith("pus"));
Ensure.that("octopus", not(endsWith("pee")));

UsingLogicalMatchers

Using this class, it's possible to negate any matcher and define matcher compositions using AND, OR, EITHER, BOTH. This class for me is the most powerful one, it gives us a wide range of interesting possibilities. Let's try some of them, so you can see how far you can go.

1 - Using conditional matchers:

String horse = "horse";
String cow = "cow";

Ensure.that(horse, or(eq(horse), eq(cow)));
Ensure.that(cow, either(eq(horse), eq(cow)));

Ensure.that(horse, and(eq(horse), contains("ors")));
Ensure.that(cow, both(eq(cow), endsWith("ow")));

2 - Using negative matcher:

Ensure.that("horse", not(eq("cow")));

There are still a couple of matchers to talk about, one is the UsingEqualityMatchers class which is pretty much like JUnit Assert class, and the UsingExceptions class. Both also deserves your attention. Maybe someday I talk about them here. :)

11Jun/070

Value Objects & RoR

Currently I'm working on my personal project, aiming to increase my Ruby On Rails skills. It's quite a simple system for my dad's company and one of the features is to register his clients. I started it out writing the Specs and as I'm new to the Ruby world, doubts started to pop inside my head. I was wondering how to use Value Objects ( Eric Evans definition, please! ) integrated with RoR, something I can do with Java as shown below:

public class Phone() {
    private int code;
    private int number;
    ....
}
public class Client() {
    private String name;
    private Phone home;
    private Phone mobile;
    ....
}

Chatting with Carlos Villela, he advised me to take a look at composed_of feature, that it would help me get the solution for my problem. The final result is shown below. I'm definitely not used to the Ruby syntax yet, for me it's still a bit confusing.

class Phone
  attr_reader :code, :number
  def initialize(code, number)
      @code, @number = code, number
  end

  def ==(other)
      code==other.code && number==other.number
  end
end
class Client < ActiveRecord::Base
  composed_of :home, :class_name => "Phone",
        :mapping => [ %w(home_code code), %w(home_number number) ]
  composed_of :mobile, :class_name => "Phone",
        :mapping => [ %w(mob_code code), %w(mob_number number) ]
end
25Jan/070

[WTF] Eureka!

If you think you know how to work out the age of a person, based on his date of birth, it'd be better to review your concepts about implementing this functionality. Enjoy the code!!

    public UserImpl( UserTO user, String status ) {
        _user = user;
        _status = status;

        _age = 0;
        Calendar today = Calendar.getInstance();
        Calendar birthdate = Calendar.getInstance();
        birthdate.setTimeInMillis( getBirthdate().getTime() );
        birthdate.roll( Calendar.YEAR, 1 );
        while ( today.after( birthdate ) ) {
            birthdate.roll( Calendar.YEAR, 1 );
            _age++;
        }
    }
Tagged as: , , , No Comments