You are on page 1of 227

Introduction to Design Principles

CSE325: Information System Design

Introduction to Design Principles 1 / 94


Contributors

Contributors

Saira Yeasmin - 1805037


Md. Mehedi Imam - 1805039
Md. Asif Shahriar - 1805040
Sanjana Binte Siraj - 1805041
Debojit Pandit - 1805042
Aroma Hoque - 1805058

Subsection: A2, Group: 04

Introduction to Design Principles 2 / 94


Importance of OOP

Importance of Object Oriented


Programming

Introduction to Design Principles 3 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Introduction to Design Principles 4 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Basic terminology and ideas of OOP are:

Introduction to Design Principles 4 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Basic terminology and ideas of OOP are:


Objects Classes

Introduction to Design Principles 4 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Basic terminology and ideas of OOP are:


Objects Classes
Abstraction and encapsulation

Introduction to Design Principles 4 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Basic terminology and ideas of OOP are:


Objects Classes
Abstraction and encapsulation
Inheritance

Introduction to Design Principles 4 / 94


Importance of OOP

What is OOP?

In OOP, a software is organized as collection of discrete objects that


incorporate both data structure and behavior.

Basic terminology and ideas of OOP are:


Objects Classes
Abstraction and encapsulation
Inheritance
Polymorphism

Introduction to Design Principles 4 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction
Manageability

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction
Manageability
Reusability

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction
Manageability
Reusability
Readability

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction
Manageability
Reusability
Readability
Productivity

Introduction to Design Principles 5 / 94


Importance of OOP

Benefits of OOP

Here is a list of few benefits of OOP


Abstraction
Manageability
Reusability
Readability
Productivity
Maintainability

Introduction to Design Principles 5 / 94


Importance of OOP

Abstraction

Objects in an OOP language provide an abstraction that hides the


internal implementation details.

Introduction to Design Principles 6 / 94


Importance of OOP

Abstraction

Objects in an OOP language provide an abstraction that hides the


internal implementation details.
It helps to just ignore the internal complexities and work with black
boxes that work great.

Introduction to Design Principles 6 / 94


Importance of OOP

Abstraction

Objects in an OOP language provide an abstraction that hides the


internal implementation details.
It helps to just ignore the internal complexities and work with black
boxes that work great.
By using encapsulation and defining classes with well-defined
interfaces, OOP provides a high degree of abstraction.

Introduction to Design Principles 6 / 94


Importance of OOP

Example of Abstraction

Introduction to Design Principles 7 / 94


Importance of OOP

Example of Abstraction

A car is an object that has many features such as wheels, engine,


transmission, etc.

Introduction to Design Principles 8 / 94


Importance of OOP

Example of Abstraction

A car is an object that has many features such as wheels, engine,


transmission, etc.
While using a car, we don’t need to know all the details of how it
works. We only need to know how to drive it such as how to start the
engine, how to accelerate, brake, and steer.

Introduction to Design Principles 8 / 94


Importance of OOP

Example of Abstraction

A car is an object that has many features such as wheels, engine,


transmission, etc.
While using a car, we don’t need to know all the details of how it
works. We only need to know how to drive it such as how to start the
engine, how to accelerate, brake, and steer.
The details of how these methods work will be hidden from the user,
allowing them to focus only on the essential features of the car.

Introduction to Design Principles 8 / 94


Importance of OOP

Manageability

OOP supports modularity which allows to break large,complex


program into smaller ,more manageable components.

Introduction to Design Principles 9 / 94


Importance of OOP

Manageability

OOP supports modularity which allows to break large,complex


program into smaller ,more manageable components.
Each object in an OOP program is responsible for a specific task and
the objects interact with each other to accomplish larger tasks.

Introduction to Design Principles 9 / 94


Importance of OOP

Manageability

OOP supports modularity which allows to break large,complex


program into smaller ,more manageable components.
Each object in an OOP program is responsible for a specific task and
the objects interact with each other to accomplish larger tasks.
Then we merge and integrate different components and manage the
whole process of combination of different modules,logics and codes in
an efficient way.

Introduction to Design Principles 9 / 94


Importance of OOP

Example of Manageability

In building a software application for a car rental company,we create


an object for each component of the car rental process, such as
customer information, rental rates, rental contracts, vehicle inventory,
and billing.

Introduction to Design Principles 10 / 94


Importance of OOP

Example of Manageability

In building a software application for a car rental company,we create


an object for each component of the car rental process, such as
customer information, rental rates, rental contracts, vehicle inventory,
and billing.
Each object would be responsible for its own specific task, and the
objects would interact with each other to complete the rental process.

Introduction to Design Principles 10 / 94


Importance of OOP

Example of Manageability

In building a software application for a car rental company,we create


an object for each component of the car rental process, such as
customer information, rental rates, rental contracts, vehicle inventory,
and billing.
Each object would be responsible for its own specific task, and the
objects would interact with each other to complete the rental process.
This approach makes the code more manageable because each
object can be developed and tested independently.

Introduction to Design Principles 10 / 94


Importance of OOP

Reusability

Reusabilty means using the same code again and again without
writing it twice.

Introduction to Design Principles 11 / 94


Importance of OOP

Reusability

Reusabilty means using the same code again and again without
writing it twice.
It is a concept of OOP that is achieved via Inheritance.

Introduction to Design Principles 11 / 94


Importance of OOP

Reusability

Reusabilty means using the same code again and again without
writing it twice.
It is a concept of OOP that is achieved via Inheritance.
Reuse enables faster development,less cost and high quality of
the software.

Introduction to Design Principles 11 / 94


Importance of OOP

Example of Reusability

Introduction to Design Principles 12 / 94


Importance of OOP

Example of Reusability

In the above code,by using OOP and inheritance, we have created a


hierarchy of classes that allows us to reuse the area() method of the
Rectangle class to calculate the area of both rectangles and squares.

Introduction to Design Principles 13 / 94


Importance of OOP

Readability

OOP increases readability of the code by providing a clear and


organized structure for code.

Introduction to Design Principles 14 / 94


Importance of OOP

Readability

OOP increases readability of the code by providing a clear and


organized structure for code.
By encapsulation, the internal workings of a class are hidden from
the rest of the program. This can make code more readable by
allowing developers to treat objects as black boxes and focus on the
public interface of the class, without having to understand every
detail of how it works internally.

Introduction to Design Principles 14 / 94


Importance of OOP

Productivity

OOP promotes a structured, modular approach to programming


that can increase productivity by reducing code duplication,
facilitating maintenance and debugging, and improving the
organization of code.

Introduction to Design Principles 15 / 94


Importance of OOP

Productivity

OOP promotes a structured, modular approach to programming


that can increase productivity by reducing code duplication,
facilitating maintenance and debugging, and improving the
organization of code.
Developers can produce high-quality code in a timely and efficient
manner.

Introduction to Design Principles 15 / 94


Importance of OOP

Maintainability

It is easy to make minor changes,finds and fix errors in the code


without affecting any other part of a program.

Introduction to Design Principles 16 / 94


Importance of OOP

Maintainability

It is easy to make minor changes,finds and fix errors in the code


without affecting any other part of a program.
Since the design is modular, part of the system can be updated in
case of issues without a need to make large-scale changes.

Introduction to Design Principles 16 / 94


Importance of OOP

Maintainability

It is easy to make minor changes,finds and fix errors in the code


without affecting any other part of a program.
Since the design is modular, part of the system can be updated in
case of issues without a need to make large-scale changes.
OOP provides a well-defined interface for unit testing which helps
during software maintenance.

Introduction to Design Principles 16 / 94


Importance of OOP

Example of Maintainability

Introduction to Design Principles 17 / 94


Importance of OOP

Example of Maintainability

In this example,By encapsulating the properties and methods of an


employee within a single class, we can easily modify or extend the
functionality of an employee without affecting other parts of the program.
For example, if we wanted to add a new property to the Employee class,
such as department,we could do it without affecting others like the right
side code of the picture.

Introduction to Design Principles 18 / 94


OOP Features

Features of Object Oriented


Programming

Introduction to Design Principles 19 / 94


OOP Features

Why OOP?

There are three major features in object-oriented programming that makes


them different than non-OOP languages

Introduction to Design Principles 20 / 94


OOP Features

Why OOP?

There are three major features in object-oriented programming that makes


them different than non-OOP languages

Encapsulation

Introduction to Design Principles 20 / 94


OOP Features

Why OOP?

There are three major features in object-oriented programming that makes


them different than non-OOP languages

Encapsulation
Inheritance

Introduction to Design Principles 20 / 94


OOP Features

Why OOP?

There are three major features in object-oriented programming that makes


them different than non-OOP languages

Encapsulation
Inheritance
Polymorphism

Introduction to Design Principles 20 / 94


OOP Features

Encapsulation

Encapsulation refers to the bundling of fields and methods inside a


single class.

Introduction to Design Principles 21 / 94


OOP Features

Encapsulation

Encapsulation refers to the bundling of fields and methods inside a


single class.
Prevents outer classes from accessing and changing fields and
methods of a class

Introduction to Design Principles 21 / 94


OOP Features

Encapsulation

Encapsulation refers to the bundling of fields and methods inside a


single class.
Prevents outer classes from accessing and changing fields and
methods of a class
helps to achieve data hiding.

Introduction to Design Principles 21 / 94


OOP Features

Encapsulation Example In Java

Introduction to Design Principles 22 / 94


OOP Features

Encapsulation Example In Java

In the above example, we have a private field age. Since it is private, it


cannot be accessed from outside the class.

Introduction to Design Principles 23 / 94


OOP Features

Encapsulation Example In Java

In the above example, we have a private field age. Since it is private, it


cannot be accessed from outside the class.

Making age private allowed us to restrict unauthorized access from outside


the class. This is data hiding.

Introduction to Design Principles 23 / 94


OOP Features

Inheritance

Inheritance provides the way of achieving code re-usability

Introduction to Design Principles 24 / 94


OOP Features

Inheritance

Inheritance provides the way of achieving code re-usability


We don’t need to write the same code multiple times, again and
again,

Introduction to Design Principles 24 / 94


OOP Features

Inheritance

Inheritance provides the way of achieving code re-usability


We don’t need to write the same code multiple times, again and
again,
Rather we can use inherit a version of the given properties of one
class into the other just by extending it.

Introduction to Design Principles 24 / 94


OOP Features

Inheritance Example In Java

Introduction to Design Principles 25 / 94


OOP Features

Inheritance Example In Java

In this example, we have a base class Teacher and a subclass


BiologyTeacher. Since class BiologyTeacher extends the properties from
the base class, we need not declare these properties and method in the
subclass.

Introduction to Design Principles 26 / 94


OOP Features

Polymorphism

Polymorphism allows a specific routine to use variables of different


types at different times

Introduction to Design Principles 27 / 94


OOP Features

Polymorphism

Polymorphism allows a specific routine to use variables of different


types at different times
Presents the same interface for several different underlying data types

Introduction to Design Principles 27 / 94


OOP Features

Polymorphism

Polymorphism allows a specific routine to use variables of different


types at different times
Presents the same interface for several different underlying data types
Makes different objects to respond in a unique way to the same
message

Introduction to Design Principles 27 / 94


OOP Features

Polymorphism Example In Java

Introduction to Design Principles 28 / 94


OOP Features

Polymorphism Example In Java

In this example a superclass called Animal that has a method called


animalSound(). Subclasses of Animals are Cow and Hen. They also have
their own implementation of an animal sound (the cow moooes, and the
hen chirps etc.)

Introduction to Design Principles 29 / 94


SE Design Guidelines

Software Engineering Design Guidelines

Introduction to Design Principles 30 / 94


SE Design Guidelines

Why Guidelines?

OOP features like encapsulation, inheritance and polymorphism alone


cannot ensure readable, reusable, easily maintainable code.

Introduction to Design Principles 31 / 94


SE Design Guidelines

Why Guidelines?

OOP features like encapsulation, inheritance and polymorphism alone


cannot ensure readable, reusable, easily maintainable code.

How many classes?

Introduction to Design Principles 31 / 94


SE Design Guidelines

Why Guidelines?

OOP features like encapsulation, inheritance and polymorphism alone


cannot ensure readable, reusable, easily maintainable code.

How many classes?


How many fields and methods in each class?

Introduction to Design Principles 31 / 94


SE Design Guidelines

Why Guidelines?

OOP features like encapsulation, inheritance and polymorphism alone


cannot ensure readable, reusable, easily maintainable code.

How many classes?


How many fields and methods in each class?
if ... else if ... else if ... ... How many branches? Can you keep
track of them all?

Introduction to Design Principles 31 / 94


SE Design Guidelines

Why Guidelines?

OOP features like encapsulation, inheritance and polymorphism alone


cannot ensure readable, reusable, easily maintainable code.

How many classes?


How many fields and methods in each class?
if ... else if ... else if ... ... How many branches? Can you keep
track of them all?

Guidelines help us write good, clean code.

Introduction to Design Principles 31 / 94


SE Design Guidelines

Inheritance vs Composition

Introduction to Design Principles 32 / 94


SE Design Guidelines

Inheritance vs Composition

Inheritance: is a relationship

Introduction to Design Principles 33 / 94


SE Design Guidelines

Inheritance vs Composition

Inheritance: is a relationship
Composition: has a relationship

Introduction to Design Principles 33 / 94


SE Design Guidelines

Inheritance vs Composition

Inheritance: is a relationship
Composition: has a relationship
Which one to use?

Introduction to Design Principles 33 / 94


SE Design Guidelines

Inheritance vs Composition

Inheritance: is a relationship
Composition: has a relationship
Which one to use?
Design Guideline: Favour Composition over Inheritance

Introduction to Design Principles 33 / 94


SE Design Guidelines

Inheritance

Introduction to Design Principles 34 / 94


SE Design Guidelines

Composition

Introduction to Design Principles 35 / 94


SE Design Guidelines

Let’s create two classes, Summer and Exp.

How to find whole-cube using these two classes?

Introduction to Design Principles 36 / 94


SE Design Guidelines

Composition over Inheritance

To find whole-cube, we need both getSum() and getExp()

Introduction to Design Principles 37 / 94


SE Design Guidelines

Composition over Inheritance

To find whole-cube, we need both getSum() and getExp()


But multiple inheritance is not allowed!

Introduction to Design Principles 37 / 94


SE Design Guidelines

Composition over Inheritance

To find whole-cube, we need both getSum() and getExp()


But multiple inheritance is not allowed!
Solution: Composition

Introduction to Design Principles 37 / 94


SE Design Guidelines

Composition over Inheritance

To find whole-cube, we need both getSum() and getExp()


But multiple inheritance is not allowed!
Solution: Composition
Create another class, keep references to both Summer and Exp
classes

Introduction to Design Principles 37 / 94


SE Design Guidelines

Composition over Inheritance

Introduction to Design Principles 38 / 94


SE Design Guidelines

Why Composition over Inheritance

Introduction to Design Principles 39 / 94


SE Design Guidelines

Why Composition over Inheritance

Classes and objects created through inheritance are tightly coupled


and changing the parent or superclass in an inheritance relationship
risks breaking the code. Whereas, classes and objects created through
composition are loosely coupled, meaning that we can more easily
change the component parts without breaking the code. Hence,
composition offers much more flexibility than inheritance

Introduction to Design Principles 39 / 94


SE Design Guidelines

Why Composition over Inheritance

Classes and objects created through inheritance are tightly coupled


and changing the parent or superclass in an inheritance relationship
risks breaking the code. Whereas, classes and objects created through
composition are loosely coupled, meaning that we can more easily
change the component parts without breaking the code. Hence,
composition offers much more flexibility than inheritance
We can only inherit from one class (in Java and C#), whereas
composition allows us to use functionality from multiple classes

Introduction to Design Principles 39 / 94


SE Design Guidelines

Why Composition over Inheritance

Classes and objects created through inheritance are tightly coupled


and changing the parent or superclass in an inheritance relationship
risks breaking the code. Whereas, classes and objects created through
composition are loosely coupled, meaning that we can more easily
change the component parts without breaking the code. Hence,
composition offers much more flexibility than inheritance
We can only inherit from one class (in Java and C#), whereas
composition allows us to use functionality from multiple classes
Inheritance cannot extend final class, whereas composition allows
code reuse even from final classes

Introduction to Design Principles 39 / 94


SE Design Guidelines

Why Composition over Inheritance

Classes and objects created through inheritance are tightly coupled


and changing the parent or superclass in an inheritance relationship
risks breaking the code. Whereas, classes and objects created through
composition are loosely coupled, meaning that we can more easily
change the component parts without breaking the code. Hence,
composition offers much more flexibility than inheritance
We can only inherit from one class (in Java and C#), whereas
composition allows us to use functionality from multiple classes
Inheritance cannot extend final class, whereas composition allows
code reuse even from final classes
In inheritance we need parent class in order to test a child class but
composition allows us to test the implementation of the classes we
are using independent of parent or child classes

Introduction to Design Principles 39 / 94


SE Design Guidelines

Interface vs Abstract Class

Introduction to Design Principles 40 / 94


SE Design Guidelines

Interface vs Abstract Class

Interface

Introduction to Design Principles 41 / 94


SE Design Guidelines

Interface vs Abstract Class

Interface
Can have abstract, default and static methods

Introduction to Design Principles 41 / 94


SE Design Guidelines

Interface vs Abstract Class

Interface
Can have abstract, default and static methods
Cannot have non-abstract non-static methods

Introduction to Design Principles 41 / 94


SE Design Guidelines

Interface vs Abstract Class

Interface
Can have abstract, default and static methods
Cannot have non-abstract non-static methods
Can have only static and final variables

Introduction to Design Principles 41 / 94


SE Design Guidelines

Interface vs Abstract Class

Interface
Can have abstract, default and static methods
Cannot have non-abstract non-static methods
Can have only static and final variables
Cannot be instantiated

Introduction to Design Principles 41 / 94


SE Design Guidelines

Interface vs Abstract Class

Abstract Class

Introduction to Design Principles 42 / 94


SE Design Guidelines

Interface vs Abstract Class

Abstract Class
Can have both abstract and non-abstract methods

Introduction to Design Principles 42 / 94


SE Design Guidelines

Interface vs Abstract Class

Abstract Class
Can have both abstract and non-abstract methods
Can have final, non-final, static and non-static variables

Introduction to Design Principles 42 / 94


SE Design Guidelines

Interface vs Abstract Class

Abstract Class
Can have both abstract and non-abstract methods
Can have final, non-final, static and non-static variables
Cannot be instantiated

Introduction to Design Principles 42 / 94


SE Design Guidelines

When to use Which

Introduction to Design Principles 43 / 94


SE Design Guidelines

When to use Which

If both abstract and non-abstract methods needed, use Abstract


class

Introduction to Design Principles 43 / 94


SE Design Guidelines

When to use Which

If both abstract and non-abstract methods needed, use Abstract


class
Else, always use interfaces

Introduction to Design Principles 43 / 94


SE Design Guidelines

When to use Which

If both abstract and non-abstract methods needed, use Abstract


class
Else, always use interfaces
Reminder: You cannot inherit multiple classes, but you can
implement multiple interfaces!

Introduction to Design Principles 43 / 94


SE Design Guidelines

Example

Introduction to Design Principles 44 / 94


SE Design Guidelines

Example

Consider an application which has a database accessor layer

Introduction to Design Principles 44 / 94


SE Design Guidelines

Example

Consider an application which has a database accessor layer


A ServiceClass which calls a DBClient class

Introduction to Design Principles 44 / 94


SE Design Guidelines

Example

Consider an application which has a database accessor layer


A ServiceClass which calls a DBClient class
DBClient class is a concrete class, programmed to access Postgres
DB

Introduction to Design Principles 44 / 94


SE Design Guidelines

Example

Consider an application which has a database accessor layer


A ServiceClass which calls a DBClient class
DBClient class is a concrete class, programmed to access Postgres
DB
What if we want to switch to a NoSQL database like MongoDB
instead?

Introduction to Design Principles 44 / 94


SE Design Guidelines

Example

Consider an application which has a database accessor layer


A ServiceClass which calls a DBClient class
DBClient class is a concrete class, programmed to access Postgres
DB
What if we want to switch to a NoSQL database like MongoDB
instead?
Solution: Write an interface/abstract class AbstractDBClient, then
have concrete classes like PostgresDBClient and MySQLDBClient
implement the interface

Introduction to Design Principles 44 / 94


SE Design Guidelines

Solution

Introduction to Design Principles 45 / 94


Importance of Design Principles

Importance of Design Principles

Introduction to Design Principles 46 / 94


Importance of Design Principles

Importance of Design Principles

In software development, the main challenge isn’t just generating


output. Rather the main challenge is to make one’s code readable for
others.

Introduction to Design Principles 47 / 94


Importance of Design Principles

Importance of Design Principles

In software development, the main challenge isn’t just generating


output. Rather the main challenge is to make one’s code readable for
others.
Good design reduces the amount of code that needs to be written,
tested, and maintained, and also makes it easier to make changes to
the codebase without introducing bugs or inconsistencies.

Introduction to Design Principles 47 / 94


Importance of Design Principles

Importance of Design Principles

In software development, the main challenge isn’t just generating


output. Rather the main challenge is to make one’s code readable for
others.
Good design reduces the amount of code that needs to be written,
tested, and maintained, and also makes it easier to make changes to
the codebase without introducing bugs or inconsistencies.
Always remember, it is easy to write a code computer can
understand, but it is difficult to write code humans can
understand.

Introduction to Design Principles 47 / 94


Importance of Design Principles

Indicators for good code

Introduction to Design Principles 48 / 94


Importance of Design Principles

Indicators for good code

Readability: Good code should be easy to read and understand.

Introduction to Design Principles 49 / 94


Importance of Design Principles

Indicators for good code

Readability: Good code should be easy to read and understand.


Modularity: Good code should be modular, with each function or
class responsible for a specific task.

Introduction to Design Principles 49 / 94


Importance of Design Principles

Indicators for good code

Readability: Good code should be easy to read and understand.


Modularity: Good code should be modular, with each function or
class responsible for a specific task.
Scalability: Good code should be scalable, able to handle increasing
amounts of data or traffic without becoming slower or less reliable.

Introduction to Design Principles 49 / 94


Importance of Design Principles

Indicators for good code

Readability: Good code should be easy to read and understand.


Modularity: Good code should be modular, with each function or
class responsible for a specific task.
Scalability: Good code should be scalable, able to handle increasing
amounts of data or traffic without becoming slower or less reliable.
Testability: Good code should be testable, with a clear separation
between the code being tested and any external dependencies.

Introduction to Design Principles 49 / 94


Importance of Design Principles

Indicators for good code

Some design principles that help coders achieve these are described in the
following slides.

Introduction to Design Principles 50 / 94


DRY

DRY

Introduction to Design Principles 51 / 94


DRY

DRY

DRY stands for Don’t Repeat Yourself.

Introduction to Design Principles 52 / 94


DRY

DRY

DRY stands for Don’t Repeat Yourself.


It is a design principle stating that every piece of knowledge or
functionality in a software system should have a single representation
in the codebase, and that repetition should be eliminated whenever
possible.

Introduction to Design Principles 52 / 94


DRY

Rule of 3

Introduction to Design Principles 53 / 94


DRY

Rule of 3

Rule of 3 is a technique for upholding the DRY principle in one’s code.

Introduction to Design Principles 54 / 94


DRY

Rule of 3

The rule of 3 goes as:


Whenever a developer copy-pastes any segment of code, he should
first opt for creating abstractions and reusable code

Introduction to Design Principles 55 / 94


DRY

Rule of 3

The rule of 3 goes as:


Whenever a developer copy-pastes any segment of code, he should
first opt for creating abstractions and reusable code
If the code is still copy-pasted, he should pin the idea in his head that
he has done something wrong

Introduction to Design Principles 55 / 94


DRY

Rule of 3

The rule of 3 goes as:


Whenever a developer copy-pastes any segment of code, he should
first opt for creating abstractions and reusable code
If the code is still copy-pasted, he should pin the idea in his head that
he has done something wrong
When he goes to copy that code for a third time, he should at once
change his code structure to avoid that copy-paste at all costs.

Introduction to Design Principles 55 / 94


DRY

Cases where DRY principle is used

Introduction to Design Principles 56 / 94


DRY

Cases where DRY principle is used

Copy-pasting: If the same code block is used in multiple places in a


software system. This code should be moved to a single function or
method.

Introduction to Design Principles 57 / 94


DRY

Cases where DRY principle is used

Copy-pasting: If the same code block is used in multiple places in a


software system. This code should be moved to a single function or
method.
Hardcoded values: Hardcoding values such as file paths, URLs, or
database connection strings etc. These values should be stored in a
single location, such as a configuration file or database.

Introduction to Design Principles 57 / 94


DRY

Cases where DRY principle is used

Copy-pasting: If the same code block is used in multiple places in a


software system. This code should be moved to a single function or
method.
Hardcoded values: Hardcoding values such as file paths, URLs, or
database connection strings etc. These values should be stored in a
single location, such as a configuration file or database.
Repetitive logic: If the same logic is repeated in multiple functions
or methods i.e, evil switch, if-else blocks etc.

Introduction to Design Principles 57 / 94


DRY

Evil switch

Introduction to Design Principles 58 / 94


DRY

Evil Switch

The Evil Switch is a case, where DRY design principle comes in handy.

Introduction to Design Principles 59 / 94


DRY

Evil Switch

Let us consider the following piece of code:

Introduction to Design Principles 60 / 94


DRY

Evil Switch

Now what if there was another function getBonus like:

Introduction to Design Principles 61 / 94


DRY

Evil Switch

In both cases, we can see that the switch condition statements are same.

Introduction to Design Principles 62 / 94


DRY

Evil Switch

Now what if there were 20 functions with the same switch conditions?
And what if there were a 100 switch conditions?

Introduction to Design Principles 63 / 94


DRY

Evil Switch

Copy-pasting does seem like an easy solution at first glance, but how
can you guarantee that you have correctly copy-pasted all the switch
cases?

Introduction to Design Principles 64 / 94


DRY

Evil Switch

Copy-pasting does seem like an easy solution at first glance, but how
can you guarantee that you have correctly copy-pasted all the switch
cases?
And imagine, you need to add a new switch case, how can you
guarantee you will not miss any of the 20 places you need to add the
new case in?

Introduction to Design Principles 64 / 94


DRY

Evil Switch

This kind of switch functions which appear in multiple places in the


codebase are known as evil switch.

Introduction to Design Principles 65 / 94


DRY

Evil Switch

This kind of switch functions which appear in multiple places in the


codebase are known as evil switch.
Evil switches break the DRY principle.

Introduction to Design Principles 65 / 94


DRY

Resolving Evil Switch

Introduction to Design Principles 66 / 94


DRY

Resolving Evil Switch

Evil switches can easily be resolved to uphold DRY design principle using
strategy design pattern.

Introduction to Design Principles 67 / 94


KISS

KISS

Introduction to Design Principles 68 / 94


KISS

KISS

KISS stands for Keep It Simple, Stupid

Introduction to Design Principles 69 / 94


KISS

KISS

KISS stands for Keep It Simple, Stupid


Sometimes it is also called Keep It Stupid Simple to make the code
understandable to even stupids

Introduction to Design Principles 69 / 94


KISS

KISS

Sometimes our compact and efficient code can be rejected by code


reviewers. Why?

Introduction to Design Principles 70 / 94


KISS

KISS

Sometimes our compact and efficient code can be rejected by code


reviewers. Why?
Using a single ternary operator is OK but using nested ternary is a
red flag.

Introduction to Design Principles 70 / 94


KISS

KISS

Sometimes our compact and efficient code can be rejected by code


reviewers. Why?
Using a single ternary operator is OK but using nested ternary is a
red flag.
Using pointers along with unary operators also makes the code
difficult to understand

Introduction to Design Principles 70 / 94


KISS

Example

Let’s look at an example. Suppose we need a data structure to contain a


number of elements and find one of them when needed.

Introduction to Design Principles 71 / 94


KISS

Example

Let’s look at an example. Suppose we need a data structure to contain a


number of elements and find one of them when needed.
We can use a 2D array of m*n elements. Here the time complexity to
find an element will be O(m*n).

Introduction to Design Principles 71 / 94


KISS

Example

Let’s look at an example. Suppose we need a data structure to contain a


number of elements and find one of them when needed.
We can use a 2D array of m*n elements. Here the time complexity to
find an element will be O(m*n).
Or we can go with a Hashmap or Dictionary data structure which will
have m hashtables and each hashtable will contain n elements. Time
complexity here is O(m+n).

Introduction to Design Principles 71 / 94


KISS

Example

Let’s look at an example. Suppose we need a data structure to contain a


number of elements and find one of them when needed.
We can use a 2D array of m*n elements. Here the time complexity to
find an element will be O(m*n).
Or we can go with a Hashmap or Dictionary data structure which will
have m hashtables and each hashtable will contain n elements. Time
complexity here is O(m+n).
So, which one should we use? Definitely the hashmap one because of it’s
lower time complexity. Right?

Introduction to Design Principles 71 / 94


KISS

Example

Let’s look at an example. Suppose we need a data structure to contain a


number of elements and find one of them when needed.
We can use a 2D array of m*n elements. Here the time complexity to
find an element will be O(m*n).
Or we can go with a Hashmap or Dictionary data structure which will
have m hashtables and each hashtable will contain n elements. Time
complexity here is O(m+n).
So, which one should we use? Definitely the hashmap one because of it’s
lower time complexity. Right?

Here comes the KISS awakening. Arrays are easier to understand than
Hashmaps.

Introduction to Design Principles 71 / 94


KISS

Example

Let’s see the KISS approach

Introduction to Design Principles 72 / 94


KISS

Example

Let’s see the KISS approach


We have to understand the context here. If our data asks for a 10000
* 100 data structure, we have no other option than Hashmap

Introduction to Design Principles 72 / 94


KISS

Example

Let’s see the KISS approach


We have to understand the context here. If our data asks for a 10000
* 100 data structure, we have no other option than Hashmap
But, if we only need a data strucuture of 500 * 4 elements, Array is
the better choice. It is simple and easy to consume.
So, we have to understand the situation and data behaviour, then go for
the implementation.

Introduction to Design Principles 72 / 94


KISS

Example

Let’s see the KISS approach


We have to understand the context here. If our data asks for a 10000
* 100 data structure, we have no other option than Hashmap
But, if we only need a data strucuture of 500 * 4 elements, Array is
the better choice. It is simple and easy to consume.
So, we have to understand the situation and data behaviour, then go for
the implementation.

If the code is not simple, then we have to try to make it simple.

Introduction to Design Principles 72 / 94


YAGNI

YAGNI

Introduction to Design Principles 73 / 94


YAGNI

YAGNI

YAGNI stands for You Ain’t Gonna Need It

Introduction to Design Principles 74 / 94


YAGNI

YAGNI

YAGNI stands for You Ain’t Gonna Need It

Basically we have make sure that we are not doing anything that is not a
must.

Introduction to Design Principles 74 / 94


YAGNI

Example 1

We have learnt over time a good amount of design patterns, Creational


Design Pattern, Structural Design Pattern and Behavioral Design
Patterns.

Introduction to Design Principles 75 / 94


YAGNI

Example 1

We have learnt over time a good amount of design patterns, Creational


Design Pattern, Structural Design Pattern and Behavioral Design
Patterns.
While coding, it is very obvious that we will try to implement these
patterns.

Introduction to Design Principles 75 / 94


YAGNI

Example 1

We have learnt over time a good amount of design patterns, Creational


Design Pattern, Structural Design Pattern and Behavioral Design
Patterns.
While coding, it is very obvious that we will try to implement these
patterns.
But we have to ask ourselves the YAGNI question. Do we actually need
the design pattern we are implementing?

Introduction to Design Principles 75 / 94


YAGNI

Example 1

We have learnt over time a good amount of design patterns, Creational


Design Pattern, Structural Design Pattern and Behavioral Design
Patterns.
While coding, it is very obvious that we will try to implement these
patterns.
But we have to ask ourselves the YAGNI question. Do we actually need
the design pattern we are implementing?
We do not want to overcommit anything that is not necessary.

Introduction to Design Principles 75 / 94


YAGNI

Example 2

We can look at another scenario where we have to complete a project


which will be used for a limited amount of users for nearly 3-4 months.

Introduction to Design Principles 76 / 94


YAGNI

Example 2

We can look at another scenario where we have to complete a project


which will be used for a limited amount of users for nearly 3-4 months.
Now do we need to think about the future and make it expandable? Do
we need to go for microservice architecture?

Introduction to Design Principles 76 / 94


YAGNI

Example 2

We can look at another scenario where we have to complete a project


which will be used for a limited amount of users for nearly 3-4 months.
Now do we need to think about the future and make it expandable? Do
we need to go for microservice architecture?
YAGNI tells us not to go for them because we don’t need all those
features for now. Microservice will be a waste of time as there will not be
a lot of services availble.

Introduction to Design Principles 76 / 94


YAGNI

Example 2

We can look at another scenario where we have to complete a project


which will be used for a limited amount of users for nearly 3-4 months.
Now do we need to think about the future and make it expandable? Do
we need to go for microservice architecture?
YAGNI tells us not to go for them because we don’t need all those
features for now. Microservice will be a waste of time as there will not be
a lot of services availble.

YAGNI is all about doing what is obviously needed, no


preassumptions, no future thinking, no overcommit. We will write
only what we need right now.

Introduction to Design Principles 76 / 94


Introduction to SOLID

Introduction to SOLID

Introduction to Design Principles 77 / 94


Introduction to SOLID

What is SOLID?

Introduction to Design Principles 78 / 94


Introduction to SOLID

What is SOLID?

Five principles of Object-Oriented Class Design

Introduction to Design Principles 78 / 94


Introduction to SOLID

What is SOLID?

Five principles of Object-Oriented Class Design


Set of rules and best practices to follow while designing a class
structure

Introduction to Design Principles 78 / 94


Introduction to SOLID

History

Introduction to Design Principles 79 / 94


Introduction to SOLID

History

First introduced by the famous Computer Scientist Robert J. Martin


(a.k.a Uncle Bob) in his paper in 2000

Introduction to Design Principles 79 / 94


Introduction to SOLID

History

First introduced by the famous Computer Scientist Robert J. Martin


(a.k.a Uncle Bob) in his paper in 2000
SOLID acronym was introduced later by Michael Feathers

Introduction to Design Principles 79 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO
Then what?

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO
Then what?
SOLID means Supple which ensures that the software can be changed
with minimum effort if needed

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO
Then what?
SOLID means Supple which ensures that the software can be changed
with minimum effort if needed
Flexible

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO
Then what?
SOLID means Supple which ensures that the software can be changed
with minimum effort if needed
Flexible
Modifiable

Introduction to Design Principles 80 / 94


Introduction to SOLID

SOLID means Supple

Does SOLID mean rock solid?


NO
Then what?
SOLID means Supple which ensures that the software can be changed
with minimum effort if needed
Flexible
Modifiable
Extensible

Introduction to Design Principles 80 / 94


Introduction to SOLID

What people confuse SOLID with?

SOLID is

Introduction to Design Principles 81 / 94


Introduction to SOLID

What people confuse SOLID with?

SOLID is
Not a Library

Introduction to Design Principles 81 / 94


Introduction to SOLID

What people confuse SOLID with?

SOLID is
Not a Library
Not a Framework

Introduction to Design Principles 81 / 94


Introduction to SOLID

What people confuse SOLID with?

SOLID is
Not a Library
Not a Framework
Not a Pattern

Introduction to Design Principles 81 / 94


Introduction to SOLID

What people confuse SOLID with?

SOLID is
Not a Library
Not a Framework
Not a Pattern
Not a Goal

Introduction to Design Principles 81 / 94


Introduction to SOLID

Is Different

In any typical code there can be an entry point class A, which calls class
B, then B calls class C, C calls class D1. But when a change is required
that B should call class D2, then lots of code lines need to be changed
manually.

Figure: Breaks SOLID Principle

Introduction to Design Principles 82 / 94


Introduction to SOLID

Is Different(continued)

Figure: Maintains SOLID Principle

Introduction to Design Principles 83 / 94


Introduction to SOLID

Is Different(continued)

It is difficult to understand seeing the code that which class will be called
from C. It actually calls and Interface. Thus SOLID code is difficult from
any typical code.

Introduction to Design Principles 84 / 94


Introduction to SOLID

An Example : Notification Handler Application


The class MSG calls different classes.

Figure: Maintains SOLID Principle

Introduction to Design Principles 85 / 94


Introduction to SOLID

An Example : Notification Handler Application(continued)


The MSG calls an Interface.

Figure: Maintains SOLID Principle

Introduction to Design Principles 86 / 94


Introduction to SOLID

SOLID helps to avoid:

Introduction to Design Principles 87 / 94


Introduction to SOLID

SOLID helps to avoid:

Rigidity

Introduction to Design Principles 87 / 94


Introduction to SOLID

SOLID helps to avoid:

Rigidity
Fragility

Introduction to Design Principles 87 / 94


Introduction to SOLID

SOLID helps to avoid:

Rigidity
Fragility
Immobility

Introduction to Design Principles 87 / 94


Introduction to SOLID

SOLID helps to avoid:

Rigidity
Fragility
Immobility
Viscosity

Introduction to Design Principles 87 / 94


Introduction to SOLID

SOLID helps to avoid:

Rigidity
Fragility
Immobility
Viscosity
Needless Complexity

Introduction to Design Principles 87 / 94


Introduction to SOLID

The five SOLID Principles

Introduction to Design Principles 88 / 94


Introduction to SOLID

The five SOLID Principles

Single Responsibility Principle (SRP)

Introduction to Design Principles 88 / 94


Introduction to SOLID

The five SOLID Principles

Single Responsibility Principle (SRP)


Open/Closed Principle (OCP)

Introduction to Design Principles 88 / 94


Introduction to SOLID

The five SOLID Principles

Single Responsibility Principle (SRP)


Open/Closed Principle (OCP)
Liskov Substitution Principle (LSP)

Introduction to Design Principles 88 / 94


Introduction to SOLID

The five SOLID Principles

Single Responsibility Principle (SRP)


Open/Closed Principle (OCP)
Liskov Substitution Principle (LSP)
Interface Segregation Principle (ISP)

Introduction to Design Principles 88 / 94


Introduction to SOLID

The five SOLID Principles

Single Responsibility Principle (SRP)


Open/Closed Principle (OCP)
Liskov Substitution Principle (LSP)
Interface Segregation Principle (ISP)
Dependency Inversion Principle (DIP)

Introduction to Design Principles 88 / 94


Introduction to SOLID

SRP

Single Responsibility Principle:

Introduction to Design Principles 89 / 94


Introduction to SOLID

SRP

Single Responsibility Principle:


A class should have only one reason to change.

Introduction to Design Principles 89 / 94


Introduction to SOLID

SRP

Single Responsibility Principle:


A class should have only one reason to change.
A class should have only one responsibility.

Introduction to Design Principles 89 / 94


Introduction to SOLID

SRP

Single Responsibility Principle:


A class should have only one reason to change.
A class should have only one responsibility.
This makes the code easier to understand, maintain, and test.

Introduction to Design Principles 89 / 94


Introduction to SOLID

OCP

Open/Closed Principle:

Introduction to Design Principles 90 / 94


Introduction to SOLID

OCP

Open/Closed Principle:
A class should be open for extension but closed for modification.

Introduction to Design Principles 90 / 94


Introduction to SOLID

OCP

Open/Closed Principle:
A class should be open for extension but closed for modification.
One should be able to add new functionality to a class without
changing its existing code.

Introduction to Design Principles 90 / 94


Introduction to SOLID

OCP

Open/Closed Principle:
A class should be open for extension but closed for modification.
One should be able to add new functionality to a class without
changing its existing code.
This reduces the risk of introducing new bugs and makes the code
more reusable.

Introduction to Design Principles 90 / 94


Introduction to SOLID

LSP

Liskov Substitution Principle:

Introduction to Design Principles 91 / 94


Introduction to SOLID

LSP

Liskov Substitution Principle:


Objects of a superclass should be replaceable with objects of a
subclass without affecting the correctness of the program.

Introduction to Design Principles 91 / 94


Introduction to SOLID

LSP

Liskov Substitution Principle:


Objects of a superclass should be replaceable with objects of a
subclass without affecting the correctness of the program.
A subclass should be able to be used in place of its parent class
without causing any unexpected behavior.

Introduction to Design Principles 91 / 94


Introduction to SOLID

LSP

Liskov Substitution Principle:


Objects of a superclass should be replaceable with objects of a
subclass without affecting the correctness of the program.
A subclass should be able to be used in place of its parent class
without causing any unexpected behavior.
This makes the code more flexible and extensible.

Introduction to Design Principles 91 / 94


Introduction to SOLID

ISP

Interface Segregation Principle:

Introduction to Design Principles 92 / 94


Introduction to SOLID

ISP

Interface Segregation Principle:


Clients should not be forced to depend on interfaces they do not use.

Introduction to Design Principles 92 / 94


Introduction to SOLID

ISP

Interface Segregation Principle:


Clients should not be forced to depend on interfaces they do not use.
A class should have only the methods that are relevant to its behavior.

Introduction to Design Principles 92 / 94


Introduction to SOLID

ISP

Interface Segregation Principle:


Clients should not be forced to depend on interfaces they do not use.
A class should have only the methods that are relevant to its behavior.
This makes the code easier to understand and reduces the coupling
between different parts of the system.

Introduction to Design Principles 92 / 94


Introduction to SOLID

DIP

Dependency Inversion Principle:

Introduction to Design Principles 93 / 94


Introduction to SOLID

DIP

Dependency Inversion Principle:


High-level modules should not depend on low-level modules.

Introduction to Design Principles 93 / 94


Introduction to SOLID

DIP

Dependency Inversion Principle:


High-level modules should not depend on low-level modules.
Instead, both should depend on abstractions.

Introduction to Design Principles 93 / 94


Introduction to SOLID

DIP

Dependency Inversion Principle:


High-level modules should not depend on low-level modules.
Instead, both should depend on abstractions.
The code should depend on interfaces rather than concrete
implementations.

Introduction to Design Principles 93 / 94


Introduction to SOLID

DIP

Dependency Inversion Principle:


High-level modules should not depend on low-level modules.
Instead, both should depend on abstractions.
The code should depend on interfaces rather than concrete
implementations.
This makes the code more modular and flexible.

Introduction to Design Principles 93 / 94


Introduction to SOLID

THE END

Introduction to Design Principles 94 / 94

You might also like