Comment by projektfu
9 months ago
mrkeen mentioned dependency inversion (DI). I think it makes sense in oop for an order to have a cancel method, but the selection of this method might be better as something configured with DI. This is because the caller might not be aware of everything involved, as well.
If the system is new and there's only one way to do it, it's not worth sweating over it. But if a new requirement comes up it makes sense to choose a way to handle that.
For example, an order may be entered by a salesperson or maybe by a customer on the web. The cancellation process (a strategy, perhaps) might be different. Different users might have different permissions to cancel one order or another. The designer of the website probably shouldn't have to code all that in, maybe they just should have a cancel function for the order and let the business logic handle it. Each order object could be configured with the correct strategy.
If you don't want to use OO, that's fine, but you still have to handle these situations. In what module do you put the function the web designer calls? And how do you choose the right process? These patterns will perhaps have other names in other paradigms but the model is effectively the same. The difference is where you stuff the complexity.
> The difference is where you stuff the complexity.
Exactly. If it were so simple, why not just put everything in one big file / class? I guess we both agree that this very quickly leads to an unmaintainable mess.
So my rule of thumb is: can a feature theoretically be removed without touching the Order entity at all? If so, then NONE of the features parts can live in the Order entity (or even be referred by it).
That means: the Order entity must know nothing about customers, sales, how it stored or cached, how prices and taxes are calculated, how an order is cancelled or repeated or orders can be archived and viewed.
Because any of those features can be removed while the others keep working and using the exact same Order entity.