4 ms·
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
by dnomad 9y ago
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.
- cma 9y agoWhat 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.