Mark Needham

Thoughts on Software Development

Coding: Setters reduce trust

with 6 comments

I’ve written previously about my dislike of the way the object initialiser is misused in C# 3.0 and although I’ve also written about my preference for explicit modeling and the need for objects to act as good citizens I’ve never quite been able to articulate what it is I dislike so much about having setter methods on objects.

I’ve learnt from experience that it leads to a world of pain in our code by having the ability to setup an object after construction using setters and in a conversation with a colleague about this last week he suggested that the reason it’s such a bad practice to follow is that it makes us lose our trust in not only that object but in all the other objects in the application.

The thinking here is that if we get caught out (usually by a null pointer exception) when using an object which wasn’t completely set up at construction then we are likely to have a seed of doubt in our mind when we come across another object as to whether the same pattern has been followed with that one – we’ve lost a little bit of our belief that we can just use this object and it will work the way we expect it to.

As a result of that loss of trust we end up spending more time looking at more implementation details of an object just to check how it has been designed to ensure that we don’t get caught out.

I don’t think this is a particularly useful way to spend our time and it also adds another thing that we have to keep in our mind when looking at code, further dragging us away from the task that we originally intended to do.

Apart from when we’re creating fluent interface style DSLs I’ve always felt more pain from using setters than I’ve gained from that so when I don’t see a good reason for them – sometimes Java frameworks might need them (thanks Dahlia!) – to exist I pretty much follow the boy scout rule and try and get rid of them.

Written by Mark Needham

May 23rd, 2009 at 3:37 pm

Posted in Coding

Tagged with ,

  • http://www.partario.com/blog/ Tim Robinson

    You’re right that having extra initialization to do after constructing an object reduces trust in that class — I hate coming across code full of null reference checks (on properties that can never be null) because somebody got bitten by an exception once.

    The other thing you lose with setter properties, compared to constructor arguments, is the ability to track where data comes from and when.

    Because a property is writable, you can never be sure that some other piece of code overwrites your value later on: it turns refactoring from a single change to a constructor argument to a line-by-line search for property assignments.

  • http://wizardsofsmart.net/author/riles/ Ryan Riley

    Well said. I’m very hesitant to just rely on setters. In general, I try not to use setters whatsoever. After learning a bit about the benefits of immutability, I really have a hard time allowing things to change after they are set. I find myself using the Builder pattern to store up what I want and then passing those parameters into a constructor or loading a DTO to load my domain models. No setters necessary.

    @Tim, I don’t think you can just discount null reference checks as setter issues. I’ve seen numerous cases where nulls are passed into the constructors and caused the same issues.

  • http://morten.lyhr.dk Morten Lyhr

    Actually a setter on a real object, that pretty much always breaks encapsulation.

    On the other hand if it is data object(some call it DTO), there is no reason not to have properties with setters.

    I tend to have properties in pure data objects with no logic and no properties in my real objects. The real objects can depend on a data objects, just like it can depend on a simple type like strins, ints etc. Data objects can also be returned from real objects like the result of a calculation.

  • http://blog.mylittlepwnage.com SCdF

    You’re right in theory.

    However, I have come across situations where being able to ‘partially’ initilise objects comes in handy, mostly when it means you can create a reference to the object before all the data it requires is available.

    I once had to deal with a data structure that someone had written that was similar to a graph. Defining a node that points to another node that points back to that node was impossible without modifying the code to provide setters.

    Granted, this is due to the arguably bad design of the data structure, but I do think there are legitimate uses for this.

    As an aside, wrt the “it turns refactoring from a single change to a constructor argument to a line-by-line search for property assignments” comment– get a better IDE ;-) .

  • http://blog.typemock.com Gil Zilberfeld

    It’s an interesting point of view. I can definitely see the why you would use immutable objects, when needed.
    I do have an aversion for big constructors (with many params) as the code is less readable, and therefore lowering the maintainability of the code – the same thing we’re trying to avoid by making objects immutable.

    I do agree with a better IDE suggestion. Get the best tool you can – they will make your life easier.

  • Pingback: Good Lazy and Bad Lazy at Mark Needham