How I Learned OOP: A Nightmare
C++ was the first Object Oriented programming language. It was created by mixing C with Simula, which was invented by Alan Kay. In this article, I’ll be sharing some helpful principles I was taught for writing OOP programs.
(Is this for real? You decide!)
- 1. Use inheritance to share behaviour
- 2. Create deep inheritance hierarchies
- 3. Provide a getter for every private member
- 4. Mutable state is your friend
- 5. A class must be something you can touch
- 6. You can touch
Bean
s - 7. OOP is the only paradigm you’ll ever need
- This is satire…
Without further ado, let’s begin!
1. Use inheritance to share behaviour
As we all know, inheritance is the best way to share behaviour and reduce code duplication (after all, if you’re not DRY, you’re MOIST).
Let’s say you have a Parrot
class which can talk
, and a SpeakAndSpell
which can also talk
. Obviously, they should both inherit from a common base class so you don’t have to duplicate the talk
method! class Parrot extends AbstractBaseTalker
and class SpeakAndSpell extends AbstractBaseTalker
looks so clean, doesn’t it?
Since we’ve been so successful at using inheritance to solve this duplicated code, doesn’t it make you want to use more inheritance? Well, you’re in luck, because our next OOP best practise is:
2. Create deep inheritance hierarchies
The more code you write, the more risk there is of duplication. So as your app grows, that means that the depth and length of your inheritance chains should also grow.
(Though I prefer to think of them not as “chains”, which sounds like a you’re in a dungeon, but rather “inheritance twizzlers”, because twizzlers are long like chains, but are delicious, not like chains.)
3. Provide a getter for every private member
As we all know, in OOP when a data member is private, this means we have to provide some way for other objects to access the member! This means you should always add a getter for your private data members. This is known as encapsulation.
Oh, and don’t forget to add setters for all private data members too, because:
4. Mutable state is your friend
In the real world, things change. And because OOP is all about taking objects that exist in the real world and turning them directly into code, that means our code-objects should change too! Put the past behind you and throw caution to the wind, because OOP will free you from worrying about what something used to be. All that matters is what it is now.
When I said “OOP is all about taking objects that exist in the real world and turning them directly into code”, I wasn’t kidding:
5. A class must be something you can touch
OOP is all about modelling the real world. Every application should be like a video game full of little objects being born, frolicking about, reproducing, and eventually dying. You can’t create such an application if your classes represent intangible things. Each class should be a representation of something you can touch! Like User
, Pet
, Car
, and Square
*.
Sticking to this means that your application will be more maintainable, because literally every single thing that a User
can ever do (or have done to them) will now be in one easy-to-find location!
*As long as the square is like, made of concrete or paint or twigs or something. Abstract shapes are a no-go. See the next tip for what to do if you really have to work with abstract shapes.
6. You can touch Bean
s
If you really have to write code for something intangible (like Happiness
, Red
or EmployeeTerminationProcedure
), you should end the class name with Bean
, because you can touch beans! This trick ensures that every class in your application represents something tangible. No more abstract Happiness
just floating around in the ether; the HappinessBean
is something you can really feel, see, and taste.
Factory
is also good for this, because a factory is also something you can touch. But factories are large, complicated, smelly and dangerous, so it’s up to you whether you want that whole vibe in your codebase.
But this final lesson I was taught about OOP is the most important:
7. OOP is the only paradigm you’ll ever need
If you mix OOP with functional programming, or if you use structs-of-arrays, the ghost of James Gosling (inventor of C++) will find you and give you a good scolding, like in that Dickens novel. Because what you’re doing is basically ruining Christmas for us all.
I hope you enjoyed this advice. Now go forth and code! And most importantly, in about 3-4 years please write a blog post about how I promised you that OOP would solve all your problems, but in reality it just helped you create an enormous spaghettified mess. This is an important part of the OOP journey.
This is satire…
…or is it? Looking around the web, you’d think this is exactly how OOP has been taught. There are a plethora of blog posts that use awful examples like class Dog extends Pet
. Inheritance is introduced immediately after the class
keyword, setters and getters abound, and people treat C++ and Java as if they have anything in common with Smalltalk, Ruby or Python.
OOP education needs a reformation, now. Sandi Metz can’t do it all by herself!
I wrote this post because I frequently see bad arguments about why OOP sucks. OOP does indeed suck at many things - but for good reasons, not bad reasons. If OOP education were better, then maybe people could discuss these things with more sense and less nonsense.
And maybe if people had a clearer-eyed sense of the benefits and pitfalls of OOP, unobstructed by awful advice like the 7 points above, they would be less bitter and disappointed when they reach the inevitable limits of one paradigm. And less naive and starry-eyed about the next hot paradigm, whatever it happens to be.
(Yes, I did once see someone post about Simula being invented by Alan Kay.)