OOP Is Not For Everyone
Object-oriented programming has been around for decades and has done a great deal for software development. So why do people keep complaining about it?
It is just inevitable. When something becomes mainstream or even ubiquitous as OOP definitely is, it eventually faces a lot of criticism.
There are tons of articles on the Internet arguing against OOP, saying it is a bad idea that should be avoided.
The quality of those articles varies. One can find plenty of uninformed musings with completely flawed reasoning, but even some famous authorities like Joe Armstrong, the author of Erlang, expressed themselves as not exactly being in favor of OOP.
Sure, some of them have great points that cannot be ignored. Does this mean we have been doing wrong for so long?
Obviously not. There is plenty of evidence that OOP works well. But as with every tool, it must be implemented correctly and in the right context. And that's exactly what all critics have in common: they point out problems you may encounter with OOP when you use it incorrectly or in the wrong context.
The right tool for the right job
It would be challenging to eat your soup with a fork but you would not blame the fork for getting you splattered because it comes in very handy when eating spaghetti.
It’s the same with every tool. It could be tempting to see a particular technique as an instrument to get every job done but they all come with drawbacks and OOP is no exception.
However, OOP does not only come with instant receipts on how to develop software, it also provides a set of generally applicable principles that are useful on the whole scale of designing and implementing software systems.
Brilliant ideas behind the SOLID principles or Domain-Driven Design are in fact just additions to the object-oriented toolkit and we will find them in all modern approaches such as microservices.
For details on why OOP is still worth learning you can refer to my previous post.
Problem with examples
So, what is the right job for OOP? Historically, the object-oriented way of thinking about software was invented to tackle complex systems with a lot of business logic, so-called enterprise. And this is where it really shines.
Object-oriented thinking helps us decompose complex business logic and rules into a network of connected individuals with clear behavior and responsibilities that are much easier to reason about.
Obviously, objects are not as helpful in situations where the problem is straight-forward. Moreover, in such cases, OOP only brings additional complexity with no real benefits.
That is, if you're not working on an enterprise system, using an object-oriented approach could do more harm than good. And that's precisely what one might have found when meeting OOP for the first time: a lot of pain, no gain.
Examples and learning snippets always tend to be simple and short which does not make them ideal candidates for OOP. Trivial and oversimplified tasks solved in the object-oriented way would become unnecessarily complex and unnatural. When, for instance, implementing Quicksort, data structures and sequence of instructions are more likely to come to mind than typical OOP phenomena such as Entities and Repositories, and that is okay.
Too often, examples on OOP are also completely unrealistic. I bet all of us have seen code like
class Cat extends Animal but how many of us have ever implemented cats in our daily business (or dogs, if you are a dog person).
It's easy to fall into this trap when teaching OOP because examples like that focus on the mechanics instead of explaining the purpose.
Last but not least, many critics argue against flaws in implementation details of particular programming languages and generalize those for OOP as a whole. However, these are usually just a take on OOP and they do not necessarily represent the fundamental ideas of OOP.
A typical example of such an unpopular detail is inheritance. Inheritance is indeed uneasy to use correctly and its overuse leads to unfortunate consequences. Still, inheritance is just a controversial feature that is not even implemented by all object-oriented programming languages and it is not a representative of OOP in its purest form.
It is said software design is about trade-offs. Object-oriented programming is no exception to this rule. There are several drawbacks you should be aware of such as the famous Banana-gorilla-jungle problem, suboptimal performance, and others.
Also, object-oriented code tends to be quite verbose, depending on a particular language (compare Java to Kotlin).
OOP is great when tackling complicated domains but it is not easy to implement correctly. It requires experience and deep understanding of the fundamental principles and the domain you're about to solve.
This relatively steep learning curve is an indisputable drawback of OOP. It takes patience and time to excel in objects but it's totally worth it.
When something works for me it does not always mean it will work for you too.
This is the general truth no matter what technology we talk about. It starts with OOP and goes to microservices and all other modern buzzwords.
Yes, object-oriented programming and design is not a tool for everyone. If you're dealing mostly with integration, data processing, or performance is crucial in your system, you might prefer to stay away from it.
However, OOP has proved itself extremely handy when it comes to complex domains.
Sometimes hostile reactions to OOP are a mere product of misunderstanding its purpose and the context it suits well. Read them with caution; more precisely, form your own opinion based on genuine experience and understanding.