OOP Objects vs Data Structure Objects
In Object Oriented programming, objects in code map entities from real life.
These objects map their features and current status in properties and state.
They take their internal actions in private methods.
They take their external interactions in public methods.
But when working with frameworks and ORMs, the object that has properties and state comes from the database and is dumb.
Frameworks and ORMs warn you that you shouldn’t encapsulate behavior in this objects.
They should be as dumb as possible and just map the table from the relational databases or document from non relational ones.
Because of the way frameworks and ORMs work, there is no point fighting this and you have to accept that these objects will be dumb.
By dumb I mean they don’t have any behavior, they don’t have any functional logic, they just can’t do things.
For example:
A real life dog does things, let’s say he plays with a toy.
A dog object from OOP also does things, he plays with a toy using a public method playWithToy().
A dog from the database knows when he played the last time, but he can’t play, the service plays for him.
In frameworks you naturally put the behaviour in services that are singletons.
But a contradiction arises here.
We use the name objects for this last category.
But they only have state, they don’t have any behavior.
They seem to be objects and yet they are not.
And this is true.
They are objects because this is the representation we use most often for them.
But are something different from the Object oriented point of view.
They could do their job just as well with arrays or maps.
They are Data containers, Data structures, Data holders, bags or whatever you want to call them.
They only exist so that our data has a body to live in.
Like I said we could as well use arrays or maps, it’s just more convenient to use objects.
From the Object Oriented point of view they are not objects.
So we will see in code are two types of objects.
There is the classic object from Object oriented programming.
Inside such an object you should avoid writing getters and setters.
You should encapsulate your state and only expose what you really have to.
You should use tell don’t ask to get things done with objects.
We will discuss tell don’t ask in a later episode.
Getters and setters also attract coupling.
This is because a lot of objects will know the internals of your object, things that maybe they should not know.
That is because they can find out everything about it using getters and they can change its state in any way they want using setters.
Instead of classic getters you might want to return information in a more informative way.
For instance instead of getLastTimeDogPlayed() you can have something like isHappy().
This might not only be one parameter.
It will encapsulate some behaviour but exposes something that the system cares about.
Other objects don’t need to know about your object internal mechanisms.
They don’t need to know that you have a lastTimeDogPlayed property.
What they really care about is if you are happy or not.
Besides reducing coupling it is also easier to refactor.
You decide you should store your play time in some other way?
No problem.
The isHappy method will still work so the external system will not change or need to know.
You will only be touching your own class because your state is encapsulated.
The second type of objects are the Data Structure classes, or data classes, or data holders.
These are objects that hold data.
For example objects holding a row from a database.
Objects that map a json.
Data transfer objects.
This type of objects are the opposite of traditional objects.
They should have all their state exposed and they shouldn’t encapsulate anything.
At most they should have methods for providing their data more convenient.
Like getFullName besides getFirstName and getLastName.
I know developers that leave this kind of objects without setters and getters and just have their properties public.
I’ve tried this for a while and didn’t find any major problems with it.
So, don’t be confused the next time you see a data object and feel like encapsulation and entity behavior are missing.
Remember this distinction about Real objects versus Data Objects.
This article is part of the “OOP Objects vs Data Structure Objects” episode from my Clean Code course.
You can watch the Clean Code courses here:
– Watch Clean code with Java examples course on Udemy
– Watch Clean code with PHP examples course on Udemy
– Watch this Clean code with Java examples – Basics for free here AND get 2 FREE months of skillshare.com Premium