OOP Mistakes - OOP oops!

So far, we’ve covered ways to use OOP well.

We’ve seen a lot of techniques that make code readable, easy to test and compact. Remember how easy it was to combine Repository with Cache with Decorator and get a pluggable speed boost?

It turns out that not everybody agrees that OOP is a good thing.

In part, of course, they are right. Plenty of things just are not suited to OOP. I can think of simple batch scripts, build scripts and Terraform scripts that set up infrastructure. We also have ‘Serverless Designs’, which use many small functions to do their work. OOP often gets in the way there.

Another driver of non-OOP designs has been processing power limitations.

For decades, CPUs followed Moore’s Law. Computing power doubled every two years. But then it hit a physical limit. CPUs had as many transistors on them as could be fitted. “I cannae change the laws o’ physics!” said Scottie in Star Trek; So it is with photolithography. A transistor can be made only so small, but no smaller. Then physics fights back.

To get around this, CPUs created multiple cores - multiple copies of a CPU design on the same chip.

This impacted software design. Suddenly, we needed parallel processing rather than sequential. The kinds of state that lived inside one object of OOP was not accessible to other CPU cores. OOP became less useful as a model of communicating state across CPU cores. Functional Programming - “stateless” programming - is useful here.

However, none of that was what gave OOP a bad name. What gave it a bad name was OOP done wrong.

So, what are the common mistakes?

Broken Encapsulation - Getters Galore!

At Number 1 in my chart of badness, a very common error:

 1 class User {
 2     private String name ;
 3 
 4     // This is painful to type ...
 5     public String getName() {
 6         return name ;
 7     }
 8 
 9     // ... so is this
10     public void setName( String name ) {
11         this.name = name;
12     }
13 }
14 
15 class UserGreeter {
16 
17     // I swear fairies and kittens are dying right now
18     public void greet( User u ) {
19         System.out.prinltn( u.getName() );
20     }
21 }

We’ve all seen this - getters and setters everywhere!

It makes me sad. It really does.

Now, to be fair, Java has to take a lot of blame for this. Right from version 1.0, Java had this idea of “Java Beans” which were things like User above.

You had fields, but every field had a getter and setter. Somehow, that became A Thing (TM), and it was used everywhere. Then taught everywhere. Then somebody decided this was an “object” - because it is in a class and has private data and public methods.

This caught on with developers who had understood procedural programming but hadn’t yet learned OO. They hadn’t learned about objects exposing behaviour and hiding secrets.

When you think in that way, every problem looks like getters-and-setters. Object secrets are made un-secret. Code that should be a method on the User object now appears in some redundant “class” UserGreeter. It’s not really a class, because it doesn’t really have any real secret. It has stolen a secret from User.

It’s just procedural programming, plain and simple.

Procedural designs simply do not gain the benefits of OOP. But they do have the words ‘class’ and ‘private’ in them. To the uninformed, they look like an OO design. But they are not.

When people criticise OOP for not delivering on its promises - but base it on code like this - it is obvious where the fault lies: This one is on them.

If you don’t even realise your code is not OOP, then don’t criticise OOP for your code!

Broken Inheritance

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.

Bird extends Animal

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.

Square extends Rectangle

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.

Inheriting implementation

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.

Broken Shared State

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.

Ordinary Bad Code

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.