« Kathy's zones of emotion | Main | Theory P: Software Development is Probabilistic »

November 16, 2007



"There's no language..."


Ryan Allen

>> There's no language that I'm aware of that supports defining ordering dependencies for the methods of an object.

How about a State Machine / State Pattern? That can determine what order methods are called in. What do you think?

Peter Harkins

I've dealt with this by writing my own little API to wrap the object, subclassing it, or monkeypatching it. The answer to all problems is another layer of indirection, right? Yeah, not really a bag of wonderful, but at least it keeps the ugly bits in one well-labeled place instead of speckled throughout my code.

Ryan Phelps

I agree. It's amazing how many badly designed APIs there are out there that have this problem, like requiring a start() method to be called before publish() will work, yet never giving a hint as to why nothing happened when you called publish(). I recently got burned by that. Although I'm hesitant to turn it into dogma, this should be more or less common knowledge among developers.


Sometimes when an object represents some kind of external resource you end up with the situation you describe here. A classic example is files, first you open the file, then you process it, then the close() method should be called at the end. The same sort of thing is common when dealing with databases.

But if its just a regular object that isn't tied so something external to the VM then there should rarely be any reason for order dependencies. A constructor method should do everything thats needed to fully initialize an object and establish all its invariants.

J. B. Rainsberger

Also known as "programming by accident", it's a clear sign that the two methods do not belong on the same class.

Marcel Popescu

Ok... I'm missing something (or rather, I don't understand how come everyone else is missing it). Objects *are* state machines. You call methods to change their state. Of course invoke order matters, that's the whole point of having an object, if it didn't we'd have independent functions.

(As an example, of course the GetAge() method will return garbage if you forgot to call the SetDOB() method first. What else could it do?)

Jonathan Dodds

That's an interesting take on objects.

What else can GetAge() do? It can fail. Failing is better than returning garbage. In languages that support exceptions, GetAge() can fail by throwing an exception.

Objects can have state. If having state makes an object a state machine then that state machine should be constrained in certain ways. Required starting state should be created in the constructor and transitions should be allowed between all allowed states. Going back to your example, you could design an object where having no DOB value is not an allowed state.

Marcel Popescu

Agreed. I'm trying to find a circumstance where it's better to return garbage and I can't find it :)

Yes, one reason for encapsulation, for private fields hidden behind methods, is to make sure that the object's state is always consistent. In a Stack class, we hide both the array and the stack pointer behind the Push/Pop methods, so that they're always in sync.

I was just objecting to the idea that call order shouldn't matter. It's an ambiguous statement - it can mean "methods should always return valid results or error out", as you apparently meant here, or "the return value of a method should not be influenced by what other methods have been called before". The second is true for Math.Sin(), but that's because Math isn't an object, it's a package where we put independent functions. It cannot (in general) be true for objects, we want the methods to influence the internal state *and* be influenced by it.

Jonathan Dodds

You're correct that I'm not saying that the state of an object shouldn't change. Of course the state can change.

And, yes, call order matters as to what the current state of the object is at any given point in time. But in terms of the semantics of the interface that an object presents, call order shouldn't matter.

The comments to this entry are closed.