In my recent project, I thought and discussed deeply about what object-oriented we should use for our project.
I realized there are so many of them. There is not one which is absolute right or wrong. And sometimes, more annoying, some of them may even look like conflicting to each other. Like
"Tell don't ask" vs. "Single Responsibility".
Previously, I think they do conflicts with each other. But after a while, I realized that not really. "Single Responsibility" doesn't mean there could be only one method. It could be "manage order entity" as the single responsibility of an OrderManager class which has multiple methods like create/update/delete, etc.
I also get challenged a lot by people about the "
Composite over inheritance" rule. I personally like to use inheritance to provide a default implementation of a plugin or strategy, and allow the really implementation to inherit from the default one and only override the methods they interest in.
Almost anytime, people will just say don't use inheritance, use composite, when reviewing my code. And of course, we could use composite to implement it. But if inheritance works well for it, why do we literally want zero inheritance and only prefer composite?
If we check "
Composite over inheritance" from Wikipedia, the example is basically factor out the functionality of a class into a couple of features or strategies, like Flyable, Quackable, etc. But look closely, when providing the implementations of these features/strategies, we already use "implements", since each of them is just a simple interface with just one method. But what if it's not that simple, and has more than one methods? We may want to provide a default implementation of methodA and methodB, and let the other implementation to selectively override either methodA or methodB or both. Here we will need inheritance again. In this case, I don't see a problem with inheritance at all.
So, we should not blindly follow any OO design principles, try them by yourselves and summarize which principle works well in which cases and works not well in which other cases. There is always a thing called refactory which could help you to get to a better design/implementation as long as you have good test coverage.
Simply saying which OO design principle is right and must be followed without mentioning the use cases or contexts is blind. Be bright and wise.