Sunday 7 February 2016

In Defence of OOP



Although probably still a minority opinion there are voices out there that say that Object Oriented Programming (OOP) is a failure and that procedural/functional programming is the new king of paradigms.
Assuming there is one hammer for all nails is a very limiting view of the world and there are definitely situations where OOP is not the most effective answer but in criticising its use we have to be sure we aren't just criticising bad practitioners.
It is all too easy to write bad OO code but does that mean OOP itself is bad? If you show me a language or paradigm where its impossible to write bad code then I'll show you a system where its impossible to creatively find solutions to difficult problems. 
Dragged Down by the Noun
When were first exposed to OOP at college or university were often asked to think about everything fitting into a noun model.
The idea behind this is to demonstrate the ability of OOP to map the problem domain, it can represent the model you have in your head as classes in your code.
Those arguing against OOP will point to the fragility and inadequacy of trying to represent everything this way, software performs tasks and we need verbs as much or maybe more than nouns.
Good naming of classes is difficult, it should provide a good description of what the class represents or the task it performs whilst maintaining encapsulation and abstraction to hide the detail, but this is generally caused because it forces you to think about the design of your system and how the blocks fit together.
I would argue that no paradigm should be aiming to absolve you from the responsibility of having to think about the design of your code, that is the essence of engineering.
Getting Ourselves into a State
Many attacks of OOP will point to the dangers of mutating state and the non-deterministic chaos that can ensue.
An abundance of state, especially when its presence is not clearly signalled, does lead to all sorts of problems with readability, testability, maintainability and can make it difficult to achieve high levels of performance from parallelisation and other techniques.
We should be trying to eliminate as much state from our code as possible and create a deterministic system whose outputs are predictable and testable given any input.
But is it realistic to remove state from the equation entirely? At some point our code has to interact with the real world where state exists in everything we do, we may chose to have this state exist only in a database but does that mean its been eliminated.
Most issues with state are around badly managing its transition and having it exist in more than one place masquerading under different names, good design will solve this problem while being realistic that it cant be remove entirely.
Inheriting Problems
A large number of the issues cited against OOP are symbolised by inheritance, detractors will provide examples of confusing spaghetti code with inheritance as the mechanism for confusion to spread.
I think this particular criticism of OOP is entirely justified, inheritance is the nuclear option that too many developers rely on as a crutch for any situation where its not clear what the relationship between different classes should be.
While its possible to do almost anything without having to use inheritance its unrealistic to try and eliminate it entirely from our thinking. Inheritance has its uses and is usually key to the frameworks that define the overall structure of our systems (MVC, MVVM etc).
My disagreement with OOPs detractors is that the problems with inheritance are so bad that it undermines the use of OOP entirely.
Any structure or paradigm for writing code that is useful enough to be applicable in many varied situations is also likely to provide enough rope to bad developers to get themselves into an awful mess.
We have now been working with OOP in mainstream software development for bordering on 30 years, we have used it to advance the state of our art and write software that solves an increasing number of diverse problems.
To now suggest that all of that progress has been a waste of time seems slightly frivolous and maybe even reckless, is it not more sensible to say that this experience has taught us that we can develop different ways of thinking for different problems.
Functional programming is a brave new world in software engineering and it will allow us to progress our industry into even more useful and innovative ways but any time we say one way of thinking is the answer to all ills we are making a mistake, in the same way that badly written code that ignores good engineering discipline and practices is not an argument that a whole generation of learning is wrong.  

No comments:

Post a Comment