It was about 15 years ago when I first created my first class.
I went from thinking of Object Oriented programming as this awesome paradigm I should know about, I remember having all these mental models of what objects where and learning all this new vocabulary that I really didn’t fully grasp until years later when I was designing and implementing bigger more complex systems.
At first I remember looking at objects as a collection of functions that kept a common reference to keep internal states and missing out on all the great features of inheritance and abstract classes. Looking at “interfaces” and using them like a recipe without really knowing their true power, I look at the past and I was so limited, hopefully I’ll look at this post 15 years from now and think the same.
There’s lots of books out there on best programming practices you should follow, on this short post I’ll share with you 6 principles that I follow that I promise you will make your code behave really well, less bug prone, simple and elegant when it comes to Object Oriented design. This advice will probably apply better if you code in a language like Java or C#, I’m not sure if you can say these principles will apply 100% to other OO languages (for instance those that allow multiple inheritance)
1. DRY principle.
This is one of the most preached ones, and I will also preach it. DO NOT REPEAT YOURSELF. Really, don’t. It ALWAYS comes to bite you in the ass if you have repeated code. Only repeat yourself if it’s too hard to not do so or if you’re absolutely sure that you won’t repeat yourself a third time, but I promise you that third time will come if it’s not for you for the next guy maintaining that code.
The obvious benefit of not repeating yourself is that you get to maintain code only in one place, the added benefit will be that your code will almost start being written by itself like a perfect equation as it grows. DRY code will be reusable, maintainable and the other principles I’ll talk about are related to the DRY principle in one way or another.
2. Keep the scope at the minimum, be as private as possible.
Keep your variables as close to your local scope as possible. This will save you many headaches, will protect you from bugs in logic because you did something to a variable in place where it shouldn’t have been in the first place, and it will keep things simpler.
This also tells you that your classes should expose as little as possible. Keep your variables local, if they can’t be local, try to keep them as private members, if they have to be used by extending classes keep them private, only use public when you really know it’s ok to make something public and that nobody is going to break the behavior of your object if they play with things at any point in time.
Keeping scope at a minimum can also prevent issues on longer lived objects like singletons that might be accessed by different objects. If you abuse the use of object properties you could have one object changing the internal state of the object while another tries to do something and you’ll get unexpected behavior, this tends to happen a lot in multithreaded environments where programmers are not careful and forget objects might be accessed by different threads/clients at the same time, tight scopes will protect you.
3. Be functional
Sometimes you’ll be tempted to be lazy and not pass parameters on a method and think that you’re so clever by changing an internal property of an object so that another function in the object will then get it. Big mistake buddy. This can be equivalent to that advice from functional programming languages where you’re told that using global variables are a bad idea.
Yes, we have object properties for several reasons, but if the logic of a method depends on the state of a variable, you might as well be explicit and pass it in the method.
This is in a way related to keeping scope at the minimum, and to some extend related to the advice some give of keeping your objects as immutable as possible.
4. Only abstract classes are worth extending.
If you have control over the class you are about to extend (if it’s in your codebase) before you extend that class take a look and make sure that it’s an abstract class. Abstract classes are MEANT to be extended, so you can be safe that you’re doing the right thing here.
If you’re extending a non abstract class, you should probably be composing it instead. If you don’t have access to the code of the class you are extending, things could not behave as expected when you extend, not all programmers are as thoughtful as you are.
5. Keep Object lifetime as short as possible.
This goes back to keeping scopes tight and trying to avoid singletons as much as possible (as convenient as they might be), in the case of java the JRE has a better time collecting garbage and will save you from memory leak headaches. Put those factories to work.
Feel free to disent and share your favorite principles, If you’ve coded long enough I’m sure you tend to think about these things too and I’d love to learn from your experiences.