Starting With Real World
If you want to create a dolls house you may easily do that
by your own. It does not necessarily
need any upfront design. You just gather some materials (say papers) and start
building from your imagination.
Give the doll’s house to your
daughter. She will play with this and
after some time she will not like it anymore. Then you throw it away and build
another one.
Now your wife is asking you to build a house on the land you
have just purchased. Is it possible for you to build the house by your own? I
know this is an invalid question. Well, is it possible for you to start
building the house if you are provided 100 people with you? The answer is
no. If I ask why? You will instantly
give the obvious answer – “Building a house involves lot of concerns and you
need experts to handle those concerns before starting the real construction
work.”
Some concerns could be
1.
Your wife’s dream about the house.
2.
The maximum area of land availability.
3.
Your budget.
4.
Core architectural design.
5.
Floor planning.
6.
Utility planning.
7.
Car parking.
8.
And many more.
So, the first point you need to start the work is to talk
with your wife generously so that you know what exactly she wants at her house.
Then go to the construction company who
will work as a contractor to build your house. Tell them your expectation, area
and budget. You will then be sent to the
civil engineer and the architect. They will know your requirements in detail
and will do thorough analysis on that. Later the civil engineer and the
architect will come out with a design and plan of construction. They will
consider all the concerns and are expected to handle those with maximum
efficiency. The best they do it, the best your house will become. On the other
hand if the architect and civil engineer do poor work, your house will suffer in
the long run.
So, it is not you and the workers who are responsible for a
great house to construct but it is the architect and civil engineer who can
make it happen of-course backed by skilled workers who are capable of working
according to plan. If your design and architecture is great, the hardest part
is done.
I am sure as you are reading this article, you are a
software engineer. Can you relate this house construction paradigm with the
software development world?
Let us construct your house hypothetically as if it is a
software and try to relate the design strategies of this house construction
with some software design principles so that we can realize the necessity of
following standard principles while design our software.
First of all who is the client of this house? It is primarily
your wife who provided you the specification of her expectations from the
house. Then you are also the client who
will be the point of contract from client side. The construction company is the
software house who is going to work to build your house. So, an agile
environment is setup that can ensure the best production as both parties will
be in close touch all the time. Now
what?
Now, the architect and civil engineer will start analyzing
your specification to come up with a good design. In reality building a house is a very big
task. So, we will not touch too many points to make it simple. The goal will
be, the designer should design your building in the best way and we will see it
through some example building construction concerns.
Base foundation of
the building:
The civil engineer will design the base foundation of the
house. He perhaps will consider the following while doing the design:
1.
Maximum area of land.
2.
Maximum number of floors can be accommodated.
3.
How many floors you will want to construct
initially.
4.
Your plan of extension in future.
Then perhaps,
5.
How deep the foundation will be.
6.
How many piers will be needed and how they will
be distributed.
7.
Etc.
During designing the base foundation plan, the civil
engineer will need to work closely with the architect so that the distribution
of piers does not impact the interior of the building.
Now, once the foundation is done, it is closed. The piers
will be extendable and on top of that your house will be extended floor by
floor. Let’s say you will construct your
house initially with 2 floors. After some years the world under go in recession
and you lost your job. So, you want to construct 2 more floors on top of your
house using your saved money so that you can give that in rent and earn some
continuous money. Let’s say, the engineer had not considered that you may want
to construct more floors on your house. So, he designed the foundation just for
2 floors and at the top the piers are sealed. So what will you do now?
Unfortunately you have no option but demolishing your house, re-do the
foundation and construct it again. So, the engineer could have killed you. Is
not it?
On the other hand, if the engineer is good, he will do the foundation
so that you can build more floors on top of it and the piers on the top floors
are extendable. So, your base foundation
is closed for any modification but still open for extension. Here we have
learned a very important principle that is also applicable in software
paradigm. That is, you must build your
base classes of the software with enough knowledge of the module you are
developing and then expose the extension points from the base class so that it
can be extended by the child classes.
In one sentence we can tell “Your base classes will be
closed for any modification and still open for extension.” This principle is
formally known as Open-Close Principle in software world.
More example of Open-Close Principle:
See the example codes below. If you understand the Open
Close Principle you will easily see how the 1st example violating
the Open Close Principle and how the second example honoring it.
Image –
Violation of Open Close Principle
Image –
Honoring Open Close Principle
Interior Architecture
– Where to fit Air Conditioners:
As I have already said, there are so many concerns we will
have to handle to construct a house. Among all those concerns very small
concern like where to install your air conditioner in your bed room is no less
important. Say, your architect designed the room so that you have a space for
fitting air conditioner inside the window.
During his design he thought of a window air conditioner and kept a
place for that in the window. Now, the time changes, and you may like to
install a bigger air conditioner or you may like to install a split ac
replacing your old window one. What will you need to do?
One option is you change your window so that it allows you a
bigger space for the ac. But you see if you do this, the size of the window may
decrease which eventually may not be good for day light transition and air flow
of your room.
So, ideal solution could be if the space for the air
conditioner were not inside your window, rather into the wall, you could alter
the space for your new ac in the wall engaging perhaps with very low skilled
labor.
See the benefits here:
1.
You do not need to change your window.
2.
Your room will not be at risk of low ventilation
and lighting.
Do you see the problem in the design where ac is to fit into
the window? We all know that purpose of a window is to provide proper light and
ventilation to your room. So, window should have been changed only if you need
to adjust the lighting and ventilation. It was not good if you had to change
your window because you needed to install a new ac.
This flaw in your build design has similarity
with a very important software design principle. The principle says your
objects should change for one and only one reason. In other words, your objects
should always serve one and only one responsibility. Formally this principle is
known as Single Responsibility
Principle in software world.
More example of Single
Responsibility Principle:
See the simple example below. Here 2 task is done by
ApplicationSecurityContext class. One is authentication and the other is Login.
You know in modern software world there could be many ways of authenticating
users and also many ways to make the user logged to your application.
Authentication can be done through database, windows authentication, single
sign-on etc and login can be done through forms authentication, windows
authentication, LDAP based authentication etc. So, it is natural that your
application’s login and authentication mechanism can change. But if you
implement both in the same class this class gets 2 very big concern of your
application to manage. Here authentication is more of central concern of the
system and login is closely related to the client interface of the application
(Desktop app, Smart client app, Web app etc).
In this situation we must not implement this 2 concern in same class and
if we do it will clearly violate the single responsibility principle. And if we
continue to mix up these type of concerns in a single class, it will become a
BBOM gradually.
Image: Violating Single Responsibility Principle
What is the solution then?
Image: Honoring
Single Responsibility Principle
We can create a separate class for authentication. The best
approach will be to have an interface like IAuthenticationProvider
and
implement your desired authentication implementing the interface. The
FormsAuthenticationProvider
class implements the forms authentication for your
application. Later you can easily implement other mechanism of authentication
if required. So, it is honoring both Single Responsibility Principle and Open
Close Principle.
Designing the car
parking area:
In Modern buildings car parking is one of the very important
areas of concern. Your engineer and architect needs to design the piers of your
building so that your basement or ground floor can accommodate as many cars as
possible. While doing the design, they should consider the type of cars they
should support. Normally in residential houses the zips could be the largest
vehicle to support. So, your engineer should design the car parking so that
each space supports light weight vehicles. Now, if your architect and engineers
are not ver careful they may design the space only for sedan cars. The
consequence of this, when you will need to accommodate your new prado in your
car parking you cannot do that.
So, the design principle should be, each parking space
should support one light weight vehicle. In that way it should also support any
type of light weight vehicle whether it is a small car or a big prado jip.
This car parking concern also can describe another
very important software design principle. The principle says, in a system of an
object X is used and if object Y is subtype of object X then, in that system
object X should be replaceable by object Y. More formally this principle is
called Liskov's substitution principle in software world.
More Example of
Liskov's Substitution Principle:
Liskov substitution principle basically says the
inheritances that you create in your application must be correct. Here is the
classic example for which the Liskov's Substitution Principle is violated. In
the example 2 classes are used: Rectangle
and Square
. Let's assume that the
Rectangle object is used somewhere in the application. We extend the
application and add the Square class. The Square
class is returned by a factory
pattern, based on some conditions and we don't know the exact what type of
object will be returned. But we know it's a rectangle. We get the
Rectangle
object, set the width to 5 and height to 10 and get the area. For a rectangle
with width 5 and height 10 the area should be 50. Instead the result will be
100. (This example is taken from
http://www.oodesign.com/liskov-s-substitution-principle.html
)
Image –
Violating Liskov Substitution Principle
Electricity
Distribution Lines:
Among many of the utilities that you must have in your
building electricity is perhaps one of the most important one. Your engineer
and architect will perhaps need to work with an electrical engineer to design
the electricity distribution line of your building. One approach for this could
be, the whole supply of current in your building will come from a single root.
But you see this will make the whole supply chain too complicated. It will make
it very difficult to manage, extend and trouble shoot. So, what should be the solution?
In fact the electricity line should be interfaced in
multiple segments. First of all each floor may have a separate root and then
perhaps the best way would be to have each room having separate root. If you
follow this design principle, it will be very easy for you to manage and
trouble shoot your electric supply lines.
Again, this has similarity with yet another important
software design principle. This principle says once an interface has become too
'fat' it needs to be split into smaller and more specific interfaces so that
any clients of the interface will only know about the methods that pertain to
them. This principle is known as Interface Segregation Principle in software world.
More example of
Interface Segregation Principle:
Interface segregation principle is closely
related with single responsibility principle I explained earlier in this write-up.
Here creating a different interface for
IAuthenticationProvider
segregating the authentication concern from the login
mechanism. In the same way whenever we
see a single interface is becoming too heavy and entertaining more than one
concern we should segregate the interface and create interfaces for each individual
task to perform. Please see the Single
Responsibility Principle code block for this example.
Overall building
development process:
So far, we have talked about few of the concerns of your
building construction. Now let us talk about the process of the building
construct. You have engaged the civil engineer and the architect and they have
completed the design. Now, the actual construction will start. How will the
massive construction work will go through? Definitely there be a team leader.
The team leader will eventually have different teams. For example construction
workers, electricians, purchase team and so on. Now, to each team the
responsibility will be distributed and each team will have a team leader
itself. So, the team leader of the whole construction work will just know the
individual team leaders of each team. He does not need to know who the team
members are working in each team. In this way, the dependencies among different
teams are abstracted to individual team leaders. So, any change in the
requirement and design will not need to be transmitted to all of the workers
working in the project. The job of the
works is just to implement what their team leaders ask to do.
So, the principle team leader does not depend on different
teams through the team members rather he depends on different teams through the
individual team leaders. And individual workers depend on their team leader to
know what they need to implement.
This process of building construction can demonstrate
another greatly important software design principle. The principle says:
1. High-level modules should not depend on
low-level modules. Both should depend on abstractions.
2. Abstractions should not depend upon details.
Details should depend upon abstractions.
--Wikipedia
The principle is known as Dependency Inversion Principle.
More example of
Dependency inversion principle:
We
actually already have seen code example of Dependency Inversion Principle. Again you if look at the code block for single
responsibility principle you will see a
parameter of type IAutheticationProvider
is passed to the method LogIn. Here
the client of this LogIn method does not need to know the actual implementation
of IAutheticationProvider
directly rather it gets the authentication through
the abstract layer of IAutheticationProvider
interface.
Image - Dependency Inversion Principle
In modern software world there are quite a few dependency injection container that facilitates us to program honoring dependency inversion principle. Some of those are Unity
, NInject
, Windsor,
<a href="http://structuremap.net/structuremap/index.html">StructureMap</a>
etc. I have plan to have a separate write up on this later. So, keep following.
So far in this write-up I have tried to explain 5 very important design principles that we should always honor while designing and programming our softwares. Collectively these principles are called SOLID.
Image - SOLID copied from wikipedia
Beside these there are some other principles that we should have knowledge about. But again I have plan to write on those later. So, keep watching .
Thanks for your patience to read this write-up.
Your comments and feedback's will encourage me for better work in future.