Robert Cecil Martin, colloquially called "Uncle Bob", is an American software engineer, instructor, and best-selling author. He is most recognized for developing many software design principles including the one we will be breaking down today, SOLID principles.
What are the SOLID principles and why were they made?
SOLID is a mnemonic acronym for five design principles, used in Object oriented programming, intended to make software designs more understandable, flexible, and maintainable.
The goal of SOLID principles is to reduce dependencies so that engineers change one area of software without impacting others, make designs easier to understand, maintain, and extend.
What do the acronyms stand for, you ask?
S - Single Responsibility Principle
O - Open-Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D - Dependency Inversion Principle
let's get into it!
Single Responsibility Principle
This principle simply says, one class should only have one responsibility and one responsibility only.
we can achieve this by encapsulation, which is simply grouping related methods and variables together when making the class.
Here's a rough use case:
Uncle Bob wants to build a series of different buildings in his estate.
class Building(object):
Each building will have a name, a numerical identifier, doors and windows.
def __init__(name, building_name, doors, windows):
self.building_name=building_name
pin = random.randint(999, 9999)
self.building_id=pin
self.doors = doors
self.windows=windows
Two of the most important things a building can do is provide accommodation and privacy and security.
def accommodation():
pass
def privacy():
pass
We can therefore conclude that all buildings in uncle bob's estate have the single responsibility of providing privacy and security by having the ability to accomodate its guests within the four walls
The building can have extended functionality such as car parking or a dining area, but this is not applicable to all buildings. This however can be achieved by inheritance which is guided by next principle ...
Open-Closed Principle
A module should be open for extension but closed for modification.
We should write our modules so that they can be extended, without requiring them to be modified. In other
words, we want to be able to change what the modules do, without changing the source code of the modules.
Lets improve on uncle Bobs estate:
He now has a base framework that will be used as a skelaton for all buildings in the estate. But, some buildings will require extra functionality than what is in the base framework. Aside from that the extended fucntionality might not be similar to all buildings. this however does not rule out that some buildings will share functionalities.Some buildings will not need extended functionality at all.
To achieve this, we create tiny interfaces that inherit from the building object. Say we want to add parking and dining functionality
class Parking_area(Building): #extends building
pass
class Dining_area(Building): # also extends building
pass
These interfaces can now he inherited by other children classes as so
class Manyatta(Dining_Area):
pass
#the Manyatta will have a dining area in it but no parking
class OfficeBuilding(Parking_area):
pass
#The office Building will have a parking area but no dinning area
class Mansion(Dining_Area, Parking_area):
pass
#The mansion will have both a dining area and a parking area. This is called Multiple Inheritance
We can therefore conclude by saying, instead of adding functionality to the base object, we can simply create custom interfaces and inherit from the interfaces. By this, we ensure that the first principle is achieved as well as fulfilling the second.
Liskov Substitution Principle
Subclasses should be substitutable for their base classes.
This principle was coined by Barbar Liskov in her work regarding data abstraction.
Uncle bob is not home today, so his son Wanzala will be running the show today. Uncle Bob taught Wanzala everything about building, so we can trust that his work is a continuation of his fathers.
We expect, he will use the same formulae and methods his father uses and more.
This is the liskov principle. A Derived classes should extend without replacing the functionality of old classes. Which means derived classes should be substitutable for their parent/base classes. Moreover, they can be usable in the place of their parent classes without any unexpected behaviour.
Interface Segregation Principle
The dependency of one class to another one depends on the smallest possible interface.
Instead of one huge interface, many small interfaces are preferred based on groups of methods, each one serving one submodule.
to explain this, lets add a mini mall to the estate.This mall will have a parking area for all the cars coming in.
class mini_mall(parking_area):
pass
This parking area should have capacity for 20 cars, have a charging port for e-cars and a hose pipe to wash the cars.
The maisonette will only need capacity for two cars and a hose pipe.
The way to handle both needs without giving the other redundant functionalities is by creating a subclass charging_port that will extend parking area.
class Charging_Port(Parking_Area):
pass
Then change class mini_mall to inherit from Charging_Port instead.
class Mini_Mall(Charging_Port):
pass
Dependency Inversion Principle
Conclusion
Uncle Bob wrote the principles in a 2000 essay. click on this link to better understand where his mindset was as he was coming up with the principles.
Top comments (0)