Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is another important argument against class-based object oriented programming. There are only very few "objects" so small as the ones conventionally created in OOP. If money is withdrawn from a bank account, it's going to be put somewhere else. Withdrawing money from an account is not an operation on an account, but on a larger system that includes the account. So making an "account" class with a "widthdraw" method is a bad idea.

Very often a program has only one or very few meaningful state machines, and pretty much always they are "global", i.e. there is only one of its kind in a process.

Just use global state, it has the best possible syntax for OOP :-)



In the real world nobody would ever create an Account class with a 'withdraw' method. Withdrawals are always first class entities that unique IDs and states of their own. Every Withdrawal is itself a request with a lifecycle that, only if completed successfully, results in an event and changes to the system.

This example is very reductive. In a rich and constantly changing domain like banking using a state machine to model core entities like an Account almost always ends in disaster. It simply doesn't work because businesses are complex and ever-changing. Virtually every time I've seen a 'STATE' property in a core entity, especially if it's a public property, it has evolved over time to become a horrendous thing that nobody really understands but it is now integrated throughout so many codebases that people have no choice but to continue supporting it. Ugh.

The real point here is that state machines are mathematical, highly specified constructs. They do not change well. If you are working on a protocol that can be specified precisely, sure use a state machine. If you're working on a business entity think long and hard about whether these requirements are truly fundamental and will never change. And if you really do think you have a state machine at least don't make it public.


What you often see instead of a simple state enum is 5 boolean getters and a bunch of logic that has things like "panic if this bool is true and this one isn't, that should never happen." Whereas with a simple state enum representing the same thing you can often just make the invalid combinations have no representation at all.


Having worked on actual banking software, I agree that an Account object with a "withdraw" method is not a real-world thing.

But having also blogged for a while... There are no good examples that are complex enough to be realistic and yet simple enough that we can concentrate on the programming principle and not be distracted by the thing being modelled :-D

Now as to one or two state machines... This has not been my experience. I have worked on some systems that had dozens of state machines, nearly every domain model was a state machine of some kind.


Yep - The only useful explicitly coded state machines I have seen are the massive, generated ones. Like DFAs representing regular expressions.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: