So probably like many, I subscribe to the OOP philosophy of programming, although I would like to think not overly-strongly. I often find myself running into headaches with OOP problems in which, for example, there is some desired design pattern that I would like to implement because it's more OO (and therefore more maintainable, scaleable etc.). Very often there is some caveat which makes it difficult to implement the pattern without some kind of ugly and less OO workaround. I can very easily end up going around in circles between patterns/approaches because almost all of them have some very significant caveats in real-world situations. ---------- Example: ----------- I'll give you a recent example. Let's say I want to use composition over inheritance. I might refactor the code but then find that there are some contexts where the superclass/baseclass simply needs to call functionality on the subclass. So then I start having to implement a half delegate/observer pattern and half composition pattern so that the superclass can delegate behaviour or so that the subclass can observe superclass events. Then the class is less scaleable and maintainable because its unclear how it should be extended, also it is tricky to extend existing listeners/delegates. Also information isn't hidden well because one starts needing to know the implementation to see how to extend the superclass (unless you use comments very extensively). So after this one might opt to simply just use observers or delegates. However this comes with its own problems. For example the amount of events needed to observe to extend behaviour can increase very easily. So I end up needing observers/listeners/delegates for practically every behaviour. One option could be to just have one big listener/delegate for all of the behaviour but then the implementing class ends up with lots of empty methods etc. Then I might try another pattern but there are just as many issues with that. Then the next one, and the one after etc. ---------- This gets very difficult when each approach seems to have as many problems as any of the others. This leads to a sort of design decision paralysis. It is also difficult to accept that the code will end up very problematic regardless of which design pattern or approach is used. This results in a loss of motivation because "clean" code ceases to be an option sometimes. Are there any approaches to design that can help to minimise this problem? Is there an accepted practice for what one should do in a situation like this?