Earlier, I was thinking that learning of Object Oriented Programings (OOPs) is enough to write robust, scalable and re-usable application/program.
When I discussed the things with Joseph Bulger, I was shocked because I was thinking that my programming skills are within OOPs and learning of new languages like C/C++/C#/F# etc.
So, I started learning “The S.O.L.I.D Programming Principles” and still learning.
This is a very vast topic and this is not possible to leanr/explain in a one-shot. I divided this into following parts:
- Learning The S.O.L.I.D Programming Principles: Overview [Part – I] – current article
- Learning The S.O.L.I.D Programming Principles: Single responsibility principle [Part – II]
- Learning The S.O.L.I.D Programming Principles: Open/closed principle [Part – III]
- Learning The S.O.L.I.D Programming Principles: Liskov substitution principle [Part – IV]
- Learning The S.O.L.I.D Programming Principles: Interface segregation principle [Part – V]
- Learning The S.O.L.I.D Programming Principles: Dependency inversion principle [Part – VI]
Object Orieneted Programmings (OOPs) provide us the way to write, polish our program in a betetr shape and way. These are the basic points wich guide us how to write a good program.
For great Object Oriented Designs (OOD) we need to think beyond this. S.O.L.I.D principles provide us
a way to write great design, yes there are certain design patterns which guide us the same but SOLID is much before these patterns.
Hereunder, I am going to share, what I knew about these awesome principles (I will also try to use example in C# to explain the things) :
What is S.O.L.I.D
- S for SRP: Single responsibility principle
- O for OCP: Open/closed principle
- L for LSP: Liskov substitution principle
- I for ISP: Interface segregation principle
- D for DIP: Dependency inversion principle
Now, time to go and get into all five principles to understand what are these describing to us:
Learning Single responsibility principle (SRP)
Name of this principle described itself, it should have single responsibility. Who should have single responsibility? Here, we are studying/learning principles to design best classes/programs/systems.
In reference to this I would say “A class should have single responsibility”. Lets dive into ocean – can we read this like “a class should not design to do multiple activities”, so, what kind of activities
Lets think I have to design a system which provide me employee details, so, it should include activities, general I have CRUD (Create Read Update Delete) operations. Now, as per Single responsibility principle, I have to design a class, which should do any of these operations but not all of these 🙂
I am remembering my old days, when I was learning C++. Generally, I was writting 1000s lines of code in a one program contains many if..else. At that time I was happy to run thise programs
Now, today’s I do not like a method which contains more than 4-5 lines, how world changed?
When I was learning this priciple, question was in my mind, why class should not resposible for multiple responsibility? I found the answe as:
More, responsibility tied classes towards more changes in future.
Yes, this is true, if I designed a class (I will explain using my old days code in coming learning part of S.O.L.I.D), which is responsible to modify data, retrieve data and then save data. In future if there is
such kindof business requirements, where our modification or data retrieval logic would be changed then we have to change our classes many time and at many places, this would be encountered more bugs and more code changes.
Finally, we can define Single responsibility principle as :
“Class should be designed for single responsibility and there should not more than one reasons to make changes in this class. The responsibility of this class should be completely tide/encapsulated by the class.”
Learning Open/closed principle (OCP)
When, I read this principle, I thought it looks like that my class should be open or closed, I thought either one. But when I read following definition from wiki:
“software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”
I was shocked to think how it is possible to make my class open and closed and not open or close, I thought in other words how can I allow things to modify without doing actual modifications to my object, it was just confusing to me:(
I dive into OOPs (Object Oriented Programmings) for answer to my question. Lets think about abstraction; we can create a base class and overridable functions with different behavior. Yes, we can allow changes by keeping objects unchanged.
Let take an example: We have to send an email for different operations body of emails depend upon certain business rules and can contain differenr or same messages. Now, what we can do here, we can create a class like CreateEmail or whatever you want to name it, with one method BuildMessage. So, this class is only and only responsible to build email messages as per different logics as this method is overridable I can define it functionality per my choice. Isn’t it interesting and easy [In coming parts, I will try to explain in details using code-examples].
Learning Liskov substitution principle (LSP)
Here is definition from wiki :
“if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substituted for objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.)”
I understood above definition like this: parent should easily replace the child object.
To understand it bit more, lets look into example of EmailNotifications(considered in OCP, above), now lets say we need to also send this email for print what we can do? We can create a new class, lets call it NotificationsForPrint or whatever name you would like 🙂 it inherits our class EmailNotifications. Now, out both classes base and child class having atleast one similar methods.
Can we use our child class to subsititute our base class, no, in this situation never. So, we need to use inheritance, define two separate interfaces one is building message and another one is sending message and lets decide in implementation where for what we need to build and send messages. I will explain this example in details – in coming parts.
Learning Interface segregation principle (ISP)
Here is a definition from wiki:
“No clients should be forced to implement methods which it does not use and the contract should be broken into small and more specific intefaces.”
I took this correct as: “as a client why should I implement 9-methods of interface when I need only 3-methods”, isn’t it make developers life easy 🙂
This also similar to High Cohesion Principle of GRASP.
Think, can we consider our EmailNotification example (for both scenarios print and send via smtp server) ?
Learning Dependency inversion principle (DIP)
This principle remembers us Decoupling:
“High level modules should not depends upon low-level modules both should be tide using abstractions”
What does this mean? Lets take a look into our EmailNotification example once again and think why should our code decide where to send my email (smtp server or printer) at very beginning.
Why not it should automatically perform preferable action [we will take a look in details – in coming parts]? Till then take a look into this pattern on wiki.
S.O.L.I.D is an acronym introduced by Michael Feathers as:
What we learned
S.O.L.I.D is an acronym introduced by Michael Feathers as: