After learning what the Law of Demeter is really about, I wanted to go further in Object-Oriented Design with the well known S.O.L.I.D principles. Because we only truly learn something when we try to teach it, today I'm sharing with you what I learned about the O in S.O.L.I.D.
Objects should be open for extension but closed for modification. It means that we should be able to add new behaviors to an object, without touching existing code. It seems paradoxical, right ? How can we implement new functionalities without modifying existing code ?
Let's dive into an example to try to clarify this Open/Closed story.
Imagine you have a great app and you want to send a notification every time a new order is made. You have a pretty straightforward class
Notifier, with a method
notify_for_new_order that creates a
Notification with a message.
The piece of code above seems reasonable. For an application that plans not to grow, maybe it is better to keep this as it is. But if you think your application will grow (and by growing I mean changing), maybe you should view things differently.
Who knows what ?
Notifier knows about the message you plan to send for a new order ? Why does
Notifier knows about
Order at all ? Let's ask ourselves the right question : what
Notifier wants ?
It just wants to notify.
So instead of coupling
Order, maybe we could put an object that can act like an order. What is the particularity of
Order that we want to keep here ? The only thing that we need to know about order is that it is notifiable, wich means we can notify it (in Slack, by mail, or whatever).
If it looks like a duck, quacks like a duck, then it's a duck!
To improve our code, we will use something called Duck Typing. It's a funny name for a really powerful concept in Obect-Oriented Design. Duck typed objects are defined by their behavior rather than their class. Let's go back to our example and make a few changes to understand how this duck typing thing can help us :
We did not change a lot of things here. We just removed the order reference in
Notifier by including a notifiable object (the duck typed object), and added a
notification_message method in
But was it an improvement ? Yes, it was.
Notifier is not tight to
Order : you just need to give it an object that responds to
notification_message, which means an object that is notifiable. We now focus on the behavior of the object rather than its class.
"Ok, but it seems to add complexity and we did not gain so much from it", you might tell yourself.
Where the magic happens
But now imagine you want to send a new notification each time you have a new subscriber. The only thing you need to do is making your subscriber "notifiable" by adding :
And now, when you create a new subscriber, just do :
Did you just see what happened here ?!
We added a new behavior to our
Notifier class without touching it. That's what the Open/Closed principle is all about.
Notifier is now open for extension but closed for modification.
Powerful, isn't it ?
Let me know your thoughts on the subject and keep learning !