One of the most common issues I find when mentoring people on object-oriented design has to do with the mentality that many people brings when moving from other paradigms. Particularly with the ones coming from the structured programming paradigm. Let’s clear that up.
Paradigm abstraction levels
To simplify, abstraction level = level of detail. Now imagine map application, something like google map, if you zoom out you can see more terrain and, at the same time, you lost sight of some information like store and street names. This is the idea behind an abstraction level. As you go up, the detail level goes down and vice-versa. Now, how does this relate with programming paradigms?
I often explain paradigms like tinted glasses. You put on some red-tinted glasses and everything looks reddish. If you put amber-tinted glasses everything looks brighter but if you put on some dark tinted glasses everything looks darker. So it is with paradigms: like tinted glasses, they affect the way we look at the world. Programming paradigms in specific provide some constructs to represent the world. So, every time you try to explain a world phenomenon you do it using the constructs provided by the paradigm you’re currently using.
So, we can classify a programming paradigm abstraction level by it’s number of constructs: the more it has, the more details you are dealing with, and hence you’re at a lower abstraction level.
So here’s a brief table showing some paradigms ranked by this criteria:
|Functional||Function + Data Structure|
|OOP||Object + Message|
|Structured Programming||Procedures, Data Structures, Blocks, Basic Data Types|
This is by no means an exhaustive table, but you get the idea. So you can see that OOP and Functional are paradigms at a high level of abstraction, whereas Structured Programming operates at a lower level of abstraction.
So you see, OOP abstracts both data and code under one concept: an object. Just as important, it also abstracts the control flow under the concept of the message. Those are the tools available to you in this paradigm.
The root of all Evil
Well, maybe not of all evil, but surely it has brought a lot of problems. And that is: to believe that you are working on the OOP paradigm because you have an OOP compliance language while keeping a Structured Programming mindset. There, I said it. I know this will irk some people, but there’s no way around it. Let me show you.
var range = Utils.GenerateSequence(from:1, to:7);
So I think that’s pretty straightforward OO snippet, right? Except it isn’t. Let’s see how would it look like if it truly were OO.
var range = 1.To(7);
So let’s review the differences. This may be a little tricky as the differences I am referring to are not in the code itself but in the mindset that generates it. Let’s start with the code and see if we can identify the mind patterns that generate it.
Differences between the Structured Programming and Object-Oriented mindsets
The main problem I find with people I coach or work with, it’s the idea that object == data structure + procedures. The problem with this is that it becomes a limitation. So, in the statement:
var number = 1;
People tend to think of ‘number’ as data since that’s what we are assigning to it. This difference between objects and data is throwing people off in the wrong direction. Remember that there is no such thing as ‘data’ in OOP, just objects and messages. You should think of ‘number’ as an object.
On the other hand, something like:
Action action = Utils.GenerateSequence;
It’s an object that represents code. But most people use the concept of pointer as a way to explain C# delegates. Why? because to them object == data structure + procedure. Anything outside of that definition is no object to them. By the way, this is what a pointer looks like in C#:
int* ptr1 = &x;
So the main question is: are you treating a variable as a data structure that needs to be passed around to functions in order to do something with it (is acted upon)? If that’s the case you are working on a structured programming paradigm (most likely). The Math class in the .net framework is a prime example of this.
On the other hand, do you send messages (‘invoke a method’ in C#/Java lingo… don’t really like the term) to the variable to do something that requires little to no external help (acts itself)? Congratulations, that’s exactly what OOP is about.
It’s not my intention to trash any paradigm out there. Every paradigm is useful in the right context. It’s just that there is so much confusion about them that I often find myself explaining this stuff over and over. So I hope this makes it clearer for you. If you ever find yourself struggling with OOP, try taking a step back and see if you are really operating on the OOP paradigm. Who knows, you may be surprised at your discoveries (as some of my mentees had been). See you on the next post!