posted by owen on 2015-Dec-5.
A couple years ago I wrote an article on the downsides of modularity so it is quite fitting that I should try to tackle Object Oriented Programming (OOP). I decided to create this abridged/summary article because the original was very long winded which is not surprising in this day and age of cargo cults. Living in a hall of mirrors.
I am going to rant about certain traps of "pure" OOP programming for a bit (notice I emphasize the word "pure"). Because everyone uses OOP, and OOP is useful in contexts where it is not being abused. When Pure OOP is used exclusively in place of simpler structures like for-loops, arrays etc developers tend to fall into a pit. There is a strange obsession in redefining simple structures into increasingly abstract constructs. Also some people who do not understand computer programming feel that OOP will somehow bridge the knowledge gap between novice apprentices and master architects - this is not the case.
Disclaimer: I am going to kick your puppy. I am going to complain about trends and memes that you hold dear to your heart. This article is not for managers or HR people looking to solve problems with software dev project overruns - its too late. I will use a lot of random tech jargon, you'll have to use a search engine if you are not familiar with some of the terms.
Pure OOP encourages tunnel vision
Have you ever seen someone trying to create something in OOP when they could easily take the procedural approach? This happens because they are locked into the idea that OOP is the only "modern" way to write computer code, and start setting up scaffolding everywhere in case someone comes after them to maintain the code (no one ever does). Any foreign or specialized construct is seen as a step back instead of an advantage; they often have problems with; Octrees, RDBMS, JQuery, SQL, PHP, CSS, linked lists, functional programming, high thru-put, low latency, hashing etc. Everything seems like a broken hammer if all you have are OOP nails.
Pure OOP is a rabbit hole
The more object oriented code you write the more complicated it gets, the more memory it consumes, the more people you need to help write it. It never gets simpler. The only time OOP code gets simpler is when you re-factor and even then you are just re-creating a different version of the same rabbit hole to jump into. Refactoring is a certainty. You will re-factor a big OOP project at least 2 or 3 times in the dev cycle until you end up scrapping it for one reason or another.
OOP Maintenance problems
Many OOP evangelists claim that OOP is easy to maintain/read but this is only true for the original developers. Most new developers who take up old OOP projects (after the original developer has left) either re-factor, or never make any significant change to it. OOP devs fear breaking old OOP class systems plus they get bored with old systems quickly. OOP code has a upper limit to how much you can hack at it, eventually you will have to re-factor it, deprecate, LTS - see Drupal 8, Java. Simply making code easier to read has no effect on maintenance because programming is dynamic in nature - its not just about "how" you write it but "what" you write. You are writing programs for a computer, not reading class. OOP devs prefer to design their own structures, which leads me to my next point.
Pure OOP programmers hate other OOP programmers code
There is a constant battle to design the perfect class structure but no one seems be able to find the right way. Every year there is a new framework or API/Promises for something and it all gets wrapped up under the OOP bubble. No OOP programmer is brave enough to go off on their own and develop something new, so they just keep building the Tower of Pizza.
Pure OOP is inefficient and unsustainable
Lets say you design a loan class. And you have 1 million loans in your system. If you try to load all those classes into RAM so that you can call the loan.all.check_balance() function what do you think will happen? The basic mindset is that everything must be live in memory - encapsulated in a class/object so that it can be instantly accessed and the dev can masturbate syntactically. When everything gets slow they say you need to run on "modern hardware". Modern hardware, better-enhanced-ultra caching, more memory. Caching is the first sign of problems in any kind of software. There is a point where OOP overlaps with procedural and functional but this is ignored in favor of POOP.
OOP code never ends
Feature bloat is one thing but you have the case of the never ending OOP program. It is connected to the desire to build the perfect class structure. Objects that load other objects that create objects of a certain type just to do this other thing. An obsession grows within the developer to make every class as generic as possible, while at the same time writing more and more code. Then they build a plugin feature for themselves so they can build more OOP code for the OOP code to run. Round and round until it get deprecated.
OOP has long development times
You technically in this day and age write 5000 lines of boilerplate OOP code that has no output, no input, follows every best practice, compiles and passes all its tests but DOES NOTHING AT ALL. Hello world is 2 lines but a finished App is 100k plus 2 years in development. At the end they will blame the skill of the developers or the version of the software being used but the common nexus is always the pure OOP mindset.
OOP is a house of cards
I have seen this everywhere; you declare objects and you put them into a list or listen for them in a pool. Nothing can go wrong in software where the templates are hardcoded against a framework API which is hardcoded against Business Logic against MVC presentation layer which has 3 files per feature which are stored in separate folders - NOPE nothing wrong with that. Somewhere in the code is a factory that accepts a string and adds the object to a array that it monitors. Even the most advanced frameworks operate this way. There is always a singleton somewhere. Or a global variable that stores something that the objects need to share. A central point of failure or a web of dependances.
OOP bloat complicates everything it touches
At one point in the last century ASM blocks were the most complicated form of coding. You would see an ASM block in code somewhere and you would not dare touch it for fear your computer would explode. OOP has taken over this challenge. There is no upper limit to how complicated even the basic software can get if you OOP-ed it enough. Pure OOP encourages programmers to add features that users might never use - just in case. You can take a loop that counts from 1 to 5 and then write 5000 lines of OOP code that produces the same output and has tests to prove that it works. You can write 3 lines of code to read a text file OR better yet you can use an API to send it into a cloud service which creates a JSON feed that can be consumed by your twitter account that is linked to a OBJc iphone app through push notifications. You want to live forever?
Pure OOP code is syntactic sugar
Syntactic Sugar or busy code. Basically a way to organize modules and create virtual types for object pools. It may seem easier to read because of its verbosity. But you do not want "verbose code" - you want LESS code. If you can write it using 2 lines and a loop then why use promises and call backs? I imagine one day there will be best practice police that go around and reads all the code written in the world and say; "hmmm that is some sexy best practice code right there! Good job!".
Pure OOP eats its own dog food
You can have applications that are frameworks built on top of frameworks and at the same time consume APIs that they create for themselves. Inception style. Round and around. You can have a App that has a API built on a framework of APIs that publishes APIs for other apps to consume. You can build your own API or you can fork (50,000 lines of code) and make improvements and we may or may not add them into core.
Pure OOP does not take responsibility for any failures
It is as if we have not learnt anything from Java, Symphony1, STRUTS, Eclipse. No matter how many awful things that get created, we still turn a blind eye to the years spent using hundreds of different (now defunct) frameworks that produce barely functional software that we gladly threw in the waste bin as soon as Node.js came out. The common fallback is either "right tool for the job" or use X in this situation and Y in this other situation. Developers are usually blamed for failed projects, not the platform or anything else. Pure OOP is in a constant battle to define who it actually benefits; the developers? the designers? the project managers? the community? the users? the maintainers? No one knows. However, there is one common glitch in all these failed projects but no one wants to admit that their own kid is ugly.
All these scenarios will not happen in every case. There are alot of good things about OOP but there are certainly pitfalls that people live in and dance around in a circle. Pitfalls in which we swim for years and years until something new comes out and they dive it again. They create huge, painful, static pieces of software that cost millions of dollars and countless man hours as rigid as concrete. Programming is about solving problems not about wiring things up in obtuse best-practice ways. OOP is a tool that you use. Learn better ways to solve problems faster and make use of all the tools you have at hand.