Mark Needham

Thoughts on Software Development

OO: Micro Types

with 12 comments

Micro or Tiny types present an approach to coding which seems to divide opinion in my experience, from those who think it’s a brilliant idea to those who believe it’s static typing gone mad.

I fall into the former group.

So what is it?

The idea is fairly simple – all primitives and strings in our code are wrapped by a class, meaning that we never pass primitives around.

In essence Rule #3 of Jeff Bay’s Object Calisthenics.

As I mentioned on a previous post about wrapping dates, I was first introduced to the idea by Darren Hobbs as a way of making APIs easier for others to use.

In the world of Java method signatures of 3rd party libraries with minimal Javadoc documentation tend to read like so when you look at their method signatures in your chosen editor.

doSomething(string, string, string, string)

The parameter name is sometimes not available meaning that it is now almost impossible to work out what each of those strings is supposed to represent – guesswork becomes the way forward!

I noticed an even more subtle example when working on a project last year where there was a method to transfer money between accounts. It looked like a bit like this:

public void transferMoney(Account debitAccount, Account creditAccount) {
	// code
}

See how easy it would be to get those accounts the wrong way around and suddenly the money is going in the wrong direction!

I always had to look twice to make sure we were doing the right thing – it was quite confusing.

Using micro types we could solve this problem by wrapping account with a more specific class. The signature could potentially read like so:

public void transferMoney(DebitAccount debitAccount, CreditAccount creditAccount) {
	// code
}

And the confusion has been removed.

The cost of doing this is obviously that we need to write more code – for the above example maybe something like this:

public class DebitAccount {
	private Account debitAccount;
 
	public DebitAccount(Account debitAccount) {
		this.debitAccount = debitAccount;
	}
}

We’d then delegate the necessary method calls through to the underlying Account although we probably don’t need to expose as many methods as the normal account object would since we only care about it in this specific context.

I had the opportunity to work on a project led by Nick for a couple of months last year where we were micro typing everything and I quite enjoyed it although opinion was again split.

I felt it helped to keep behaviour and the data together and was constantly forcing you to open your mind to new abstractions.

The other argument against the approach is that you are creating objects which have no behaviour.

I find here that it depends what you classify as behaviour – for me if there is some logic around the way that a string is formatted when it is going to be displayed then that is behaviour and we should look to put that logic as close to the data as possible i.e. within the micro type.

On that project each object rendered itself into a ViewData container which we accessed from our views.

public class Micro {
	private string micro;
 
	public Micro(string micro) {
		this.micro = micro;
	}
 
	public void renderTo(ViewData viewData) {
		viewData.add(micro);
	}
}

If an object contained more than one piece of data it could then decide which bits needed to be rendered.

It’s certainly not for everyone but it’s an approach that I felt made coding much more enjoyable and code much easier to navigate.

Be Sociable, Share!

Written by Mark Needham

March 10th, 2009 at 10:40 pm

Posted in OOP

Tagged with ,

  • Pingback: DotNetShoutout

  • http://brianbrowning.wordpress.com Brian Browning

    Interesting post, I’ve coded using these kind of microtypes for some small projects, but eventually I gave it up, too much typing and boilerplate for too little benefit imo.

    The problems that microtypes solve could also be solved through documentation.

    You are right though, I think its a matter of opinion whether to use better documentation or microtypes.

  • http://80points.blogspot.com/ Carlo

    Generally I agree with micro-typing but I think the example maybe was a bit simple and therefore missed the mark. The transferMoney() behaviour should probably be moved closer to the Account class or a ‘Transfer Transaction Command’ or simply have a better variable naming scheme to avoid confusion.

    In Smalltalk (I’m a Java developer by trade though) I’d write something like:

    debitAccount transfer: 25 dollars to: creditAccount.
    Or
    transaction:=AccountTransaction transfer: 25 dollars from: debitAccount to: creditAccount.
    transaction transact.
    transaction rollback.
    OR best of both worlds
    transaction:=debitAccount transfer: 25 dollars to: creditAccount.
    transaction transact.
    transaction rollback.

    I guess this comes down to Rebecca Wirfs Brock’s Responsibility Driven Design and Ward Cunninghams Whole Value pattern (== Eric Evans Value Object); where should this behaviour sit and what best describes my intent.

    Personally thats why I like Smalltalk, it’s all objects and messages; and has a higher potential to describe my intent.

    Creating specific account types as you suggest has made the code more specialised and less general; Is it unreasonable to transfer money between any 2 accounts?
    Thinking about this again I’d say the issue is variable naming as the micro-typing gives you a false sense of security as somewhere in the code you’d still need to make the decision to wrap each account to classify it as either debit or credit.

    Obviously there are many more factors to be aware of in the designs above depending on what we’re asked to do.

    Keep up the great blogging…

  • Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #304

  • anon

    Could you use a more OO approach?

    public interface IAccount
    {
    // return the IAccount interface for method chaining
    IAccount Transfer(IAccount creditAccount, decimal amount);
    }

    public class Account : IAccount
    {
    IAccount Transfer(IAccount creditAccount, decimal amount)
    {

    }

    public static IAccount Load(int accountId)
    {

    }

    }

    IAccount debitAccount = Account.Load();
    debitAccount.Transfer(Account.Load(), 100);

  • http://www.hyperoceanic.com Mark Smth

    Thanks for sharing your experiences with this approach. What’s to stop you passing the wrong kind of account to the DebitAccount constructor?

    Like Carlo, my Account class would have a TransferTo(amount, targetAccount) method, thus removing the confusion.

    The micro-types I *do* miss, in C# are the strict types you could create in Pascal and Ada. eg To define a type as being a limited range of numbers. Any thoughts on implementing this kind of thing?

    [I haven't done any Smalltalk for a decade. Thanks for reminding me how cool it is, Carlo!]

  • Andy Hitchman

    For the specific example of simplifying parameter list, I recommend immutable Command objects.

    public void do(TransferMoney cmd) {…}

  • http://www.markhneedham.com Mark Needham

    @Carlo – I’ve not done any Smalltalk but I think I can just about follow the example you give!

    You’re write the example I’ve given probably is a bit simplistic and certainly it would be possible to pass in the wrong account to the constructor. Nothing immediately comes to mind with respect to how we can avoid that though.

    @anon – If I follow your example correctly then I guess the question would become where would the Transfer method be called from – it feels to me like it doesn’t really belong on either the DebitAccount or CreditAccount objects since it affects both of them?

    Maybe it should go on a Transfer object which they can both interact with.

    @Mark – nothing to stop you, you’re right! Can’t immediately think of a way to get around that.

    Strict types sounds interesting – I wonder if the code contract stuff from Microsoft would be able to help us here – http://richardsbraindump.blogspot.com/2009/02/code-contracts.html

  • Pingback: Dew Drop - March 11, 2009 | Alvin Ashcraft's Morning Dew

  • Pingback: QCon London 2009: Rebuilding guardian.co.uk with DDD - Phil Wills at Mark Needham

  • Pingback: Coding Dojo #13: TDD as if you meant it at Mark Needham

  • Pingback: C# Object Initializer: More thoughts at Mark Needham