Thursday, 22 May 2008

Singletons

I've been playing about with a code base that has a large number of singletons, for what appears to be no apparent reason.
Something about singletons doesn't sit quite right with me, but in the most part, if they're not misbehaving, I'll probably leave them be.

The thing that bothers me a lot more though, is the fact that everyone else is forced to know about your singleton-ness..

ImASingleton.getInstance().doSomething();

*shivers*

If you have to store global state, it would be nice if we could hide that from the clients. Why do we have a single instance with instance variables accessed through a static getInstance method, when we could hide (ooh, encapsulation) the implementation behind multiple instances with private static variables?
By using instance methods, we also get all the interface / testing / mocking goodness.

new ImASingletonButYouCantTell().doSomething();

OK, I'm rambling... am I missing something? (please rant below)

Wednesday, 21 May 2008

Static Utility Methods

A few of us were chatting about static methods the other day.
I'm not a big fan. I think that they tie you unnecessarily to a concrete class.

Most people were saying that there is no harm in having static methods in utility classes, and this is one place where I would disagree.
The example used was the java.lang.Math class with it's utility methods.

java.lang.Math is non-instantiable, you can only access it's utility methods through static calls.
For the most part, this is fine, but take the example of Math.sqrt(x)
This method returns NaN if x is < 0. For the majority of cases this is fine, but if I start working with complex numbers, then this is no longer the ideal behaviour.
Admittedly, in this case I would not want the return value to be a double, but I may want it to throw a ComplexNumberException or something similar. If I have used the static method throughout my code, I now have to go and update every single reference to the concrete class. What a pain in the class!

However, if I had used a utility class with instance methods, I could have injected the utility class in the constructor and I could now change it out for my new ComplexMathUtility class through configuration / DI.

This isn't the best example, as the required return types are different, but think of a String utility class, perhaps something that formats a header for a report.
We could (naively) implement this using static utility methods. If we later require two different types of report heading, this is going to make our life difficult.
If we implement this using an instantiable ReportFormatter, we can swap in new ones at runtime / configuration. We've just implemented a ReportFormatterStrategy :-)

My feeling is that implementing utilities as instance methods keeps the design flexible and allows for more code reuse as things naturally gravitate towards smaller, more easily testable, logically grouped units of functionality...
Or am I just dreaming? :-)

Saturday, 9 February 2008

Refactoring / Design: Composed Method

I'm going to try and write a few posts over the next few weeks around the subject of Refactoring and Design. This is mainly practice for me, so that when asked to explain, I don't confuse the issue. All comments and suggestions are gratefully accepted.



When I am looking at code, I feel a lot more comfortable if a method is composed of several steps of similar context, in the appropriate order.

This is the Composed Method pattern from Smalltalk Best Practice Patterns.
In Refactoring To Patterns, Joshua Kerievsky says that this is one of the most important refactorings that he knows, and I would have to agree.

Here is an example that I just thought of (see if you can guess what I was doing):


public class CheeseCake {

private final Person chef;
private final Sink kitchen;
private CakeTin<CheeseCake> cake;

public CheeseCake (Person chef, Sink sink) {
this.chef = chef;
this.sink = sink;
}

public makeBase(Ingredients... ingredients) {
sink.runUnderWater(chef.getHands());
sink.useSoap(chef.getHands());
sink.dry(chef.getHands());
Bowl<Ingredients> bowl = new Bowl<Ingredients>();
for (Ingredients i : ingredients) {
bowl.add(i);
}
bowl.mix();
CakeTin<CheeseCake> cake = new CakeTin<CheeseCake>();
cake.add(bowl.contents());
}

}


Wow, we have quite a few smells in this code, and not the pleasant smells of cheesecake cooking either...
We'll ignore the Feature Envy and things for the moment, but I've only just written this code and already I'm having trouble telling what it does at a glance...

What about if the makeBase method looked like this:


public makeBase(Ingredients... ingredients) {
washHands();
Bowl<Ingredients> bowl = addTo(new Bowl<Ingredients>(), ingredients);
bowl.mix();
cake.add(bowl.contents(); // Moved CakeTin creation into constructor
}


That looks much better, but not only that, we also find that the washHands() method is used extensively. Now each step in the recipe doesn't need to implement their own hands washing routine.

It's also much more obvious that washHands has absolutely nothing to do with CheeseCake, and much more to do with either Person or Sink... maybe we'll look at this next time :-)

Saturday, 24 November 2007

Things I Like: Mercurial Version Control

I was recently introduced to Mercurial version control. (http://www.selenic.com/mercurial/)
I haven't had enough time to play with it to tell how well it holds up in all situations, but first impressions are very positive.

Things I like (a lot):
- the repository is contained within the working directory, but only in the root, so you don't have version control artifacts spread throughout the directory structure.
- The way it handles development branches is very clever. Modifications are stored as changesets, which are then applied to a common parent. If two developers move down separate paths, it effectively creates two branches. It's possible to change between "branches" by reverting to the common parent and then applying the changesets for the other branch.
- It's possible to merge the two branches (called heads) together to return to a single main branch (There is a clever pattern that Dan North showed me using this that lets you merge a complex change back into another version control system)

As an example, here is how you would create a new repository once you have decided that you are going to bring it under version control (before you start, right?) :-)

We start in the working directory of the project:
- hg init (tell Mercurial to create a repository)
- hg addremove (add all files in this directory and subdirectories to the repository)
- hg ci -m "Created repository for Project X" (commit the changes to the repository)

The ease with which you can create a new repository along with the fact that it is stored alongside the working copy without all the versioning artifacts mean that Mercurial is going to be my version control system of choice for my personal projects going forward (sorry subversion)

Sunday, 14 October 2007

A couple of small touches

Sometimes it's the small touches that make the difference between an OK piece of software and a great piece of software.
A couple of small touches have stood out to me over the last couple of days.
Firstly, I've just loaded Gutsy Gibbon onto my laptop. In an office full of techy practical jokers it's very important to lock your screen if you wander away for a few minutes. One of the options in the password entry dialogue for Gutsy is to leave a message for the person who has locked the terminal. This is cool :-)

Secondly, I was driving home this evening when the traffic came to a very sudden stop in front of me. I had to hit the brakes hard, and while I diverted my full attention to avoiding a collision with the car in front, I noticed out of the corner of my eye that the car (Renault Laguna) had started flashing the hazard lights.
This indicated to the people behind me that this was not an ordinary circumstance, giving them maybe a little extra warning. Overall, this car has given me a fair amount of trouble, but I liked this.

Saturday, 13 October 2007

First Week

So, my first week at Thoughtworks is over.
It has been really intense, and I am exhausted.
Monday was the normal admin stuff that you deal with on your first day at any company.
Tuesday, I got assigned to a beach project (an internal non-billable project) and also asked to help out with some server migration for another project.
At least I have managed to deliver some value this week, which is nice.

Tuesday evening was Ruby Tuesday, which was interesting (and pizza was provided). You can do some crazy things with Ruby. One of the most interesting was a demonstration of defining methods on Numeric in order to convert units of length.

I don't think I got back home much before 9pm most days, and my poor couch potato legs have had to cope with walking for an hour each day.

There is a lot of energy in the TW office. You can almost feel it buzzing. So, even though I am tired, I have had a really good time.