Lecture 02
Lecture 02
Architecture
WEEK 2
SOLID-DESIGN PRINCIPLES
COU RS E I N STRU C TOR: TA ZZA I NA M A L I K
Today’s Agenda
2
SOLID Principles:
3
SOLID
• Five fundamental principles of OOD (Object Oriented
Design)...
• What is OOD ??
– In software development, OOD addresses the bigger picture. You need
to design your software in a way that your classes and code are
modularized, re-usable, and flexible.
– There are some design principles that you can apply to design your
classes and objects.
4
Why OOD?
Your software does what it is supposed to do today and does it good enough.
But, is your software smart enough to support "changes"? If not, you don't
have a smartly designed software.
1. Object Oriented.
2. Re-usable.
3. Can be changed with Applying a good "Object
minimal effort. Oriented Design" is the key to
4. Can be extended without
achieve such a smart design
changing existing code.
5
Why SOLID?
1. Those are the insights that senior developers reached after decades
of developing complex, enterprise-grade software
2. Purpose of those principles is to allow developers to write better
software
3. The software is easier and cheaper to maintain, easier to
understand, faster to develop in a team, and easier to test
4. Following those principles doesn’t guarantee success but avoiding
them will lead in most cases to at least sub-optimal results in terms
of functionality, cost, or both.
6
Principles of OOD
1. Single Responsibility Principle
2. Opened Closed Principle
3. Liskov Substitution Principle
4. Interface Segregation Principle
5. Dependency Inversion Principle
7
Single
Responsibility
Principle
8
Single Responsibility Principle
Principle:
A class should have
one and only one
responsibility.
9
10
Single Responsibility Principle
Principle:
A class should have
one and only one
responsibility.
10
11
Single Responsibility Principle
10
Single Responsibility Principle
“Robert C. Martin describes it as:
❖A *class should have one, and only one, reason to change.”[1]
❖This makes the Classes and their methods easy to read and
understand, and makes sure changes affect only the component that
needs to be changed.
12
Example:
13
Example Rectangle class performs
two things
14
Example:
A class has the task of calculating sales
tax. Because sales tax regulations vary
from province to province, the class has
to be able to calculate the tax for
multiple provinces
15
Solution:
16
Single Responsibility Principle
❖ one module/whole functionality should have the reason to change by
only one actor
17
18
19
Problem:
The module “Employee” is encapsulating
the different functions/functionality which
caters to different actors to the system.
20
But:
The module “Employee” is encapsulating
the different functions/functionality which
caters to different actors to the system.
21
Solution:
- Facade Pattern to use (we will see
it later)
- Decompose the module
◦ So, the business requirement sits in
the particular classes and the
request for change that business
logic come from one particular
stakeholder
22
Design Validation: A Simple Question
•What is the responsibility of your class/component/microservice?
•If your answer includes the word “and”, you’re most likely breaking the
single responsibility principle.
•Then it’s better to take a step back and rethink your current approach.
There is most likely a better way to implement it.
23
Open-Closed
Principle
24
Open-Closed Principle
Principle:
Software entities (classes,
modules, functions, etc.)
should be open for
extension, but closed for
modification.
25
You can add
26
Open-Closed Principle (Cont...)
27
Open-Closed Principle (Cont...)
29
Example:
30
Example (Bad and Good):
31
Liskov's
Substitution
Principle
32
Liskov's Substitution Principle
Principle:
Subclasses should be
substitutable for their base
classes
Or
Child class should be able
to replace its parent class
33
Rationale
34
Liskov's Substitution Principle
"Objects of a superclass shall be replaceable with objects of its
subclasses without breaking the application.“
-The principle was introduced by Barbara Liskov in 1987
- This principle ensures that any class that is the child of a parent class
should be usable in place of its parent without any unexpected
behavior.
-Whenever we are using *inheritance in our application we should be
able to make it sure that the child class should be able to replace its
parent class
-* the child class has inherited all the properties from its parent class so
if it had inherited all the properties from parent than it can replace
obviously
35
Liskov's Substitution Principle
- In some cases when we are not able to implement/utilize any method
in child class (that is available in the parent class) it’s the violation of
LSP
- Class B is a subclass of Class A, we should be able to pass an object of
class B to any method that expects and object of class A without giving
any weird output
A obj_A = B()
36
Liskov's Substitution
Principle
- If a function X() takes an instance
of a class C. That same function X()
should also be able to take the
instance of derived classes C1 and
C2 from that class C.
Without breaking the functionality
of function X()
37
Example:
-You can understand it in a way that
a farmer’s son should inherit
farming skills from his father and
should be able to replace his father
if needed.
-If the son wants to become a farmer
then he can replace his father but if
he wants to become a cricketer
then definitely the son can’t replace
his father even though they both
belong to the same family hierarchy.
38
Example:
39
Example:
40
Example (Bad):
41
Liskov's Substitution Principle (Cont...)
Design
Bird Violates
Fly() LSP
42
Example:
43
How to fix now?
44
Interface
Segregation
Principle
45
The Interface Segregation Principle
Principle:
Subclasses should not
be forced to depend
upon interfaces that
they do not use
46
Interface Segregation Principle
- Client should not be forced to implement interface even if it is not
required
-Create as small interface as possible
47
What if?
◦
- Instead, create another interface
pet which will have play() method
in it
48
Interface Segregation Principle
- In order to use the power of Abstraction we use Interfaces in OOD
- Interfaces: Keeping things abstract (hiding details) and let classes
implement them
49
Interface
Segregation
Principle
50
Example:
51
Fat Interface
Example of an interface violating the
Interface Segregation principle
Bird
Eat() Bird interface has many bird
behaviours defined along with
Walk() the Fly() behaviour.
Chirp()
Fly() Now, if a Bird class (say, Ostrich
class) implements this interface, it
has to implement the Fly() behaviour
unnecessarily (Ostrich doesn't fly).
Eagle Ostrich
52
Solution: Fat Interface
• The "Fat Interface" should be broken down into two different
interfaces.
Bird
Correct version of the interface in the Interface
Eat() Segregation principle example
Walk()
Chirp()
FlyingBird
Fly()
53
Example
Bird
Eat()
Walk()
Chirp()
FlyingBird Ostrich
Fly()
Eagle
54
The Interface Segregation Principle
• This principle ensures that Interfaces are developed so that
each of them have their own responsibility and thus they are
specific, easily understandable, and re-usable.
55
Example (Fat Interface)
56
Example (Compliance of ISP)
57
Dependency
Inversion Principle
58
Dependency Inversion Principle
Principle:
"High level modules
should not depend upon
low level modules. Rather,
both should depend upon
abstractions."
59
Dependency Inversion Principle
60
Explanation:
61
Example:
62
Solution
63
64
Example (Violation IDP)
65
Example(Solution)
66
Thank you
67