Design Patterns
What is Design Pattern?
Design patterns are typical solutions to commonly occurring problems in software
design. They are like pre-made blueprints that you can customize to solve a
recurring design problem or address a recurring scenario in your code.
Why Design Pattern is Required?
● Solves common, recurring software problems.
● Improves code readability and maintainability.
● Promotes code reusability and flexibility.
● Reduces development time by providing proven solutions.
How Design Patterns Can Help
● Provides time-tested solutions to common issues.
● Promotes cleaner and more organized code.
● Improves collaboration with standardized approaches.
● Helps in managing complex software architecture.
History of Design Pattern
The concept of patterns was first described by Christopher Alexander in A Pattern Language:
Towns, Buildings, Construction. The book describes a “language” for designing the urban
environment. The units of this language are patterns. They may describe how high windows
should be, how many levels a building should have, how large green areas in a neighborhood
are supposed to be, and so on.
Software Adoption (1980s): In the 1980s, the software engineering community began
recognizing the importance of reusable solutions to common problems in coding. However, the
formalization of design patterns as a discipline within software engineering began to take shape
in the late 1980s.
[Link]
History of Design Pattern
The "Gang of Four" (1994): The pivotal moment in the history of design patterns came
with the publication of the influential book Design Patterns: Elements of Reusable Object-
Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John
Vlissides. This book, known as the "Gang of Four" (GoF) book, formalized 23 core design
patterns, such as Singleton, Factory Method, and Observer. This book marked the
beginning of widespread use of design patterns in object-oriented programming (OOP).
[Link]
Why should I use Design Patterns?
1. Design patterns are a toolkit of tried and tested solutions to common
problems in software design.
2. Design patterns define a common language that you and your teammates
can use to communicate more efficiently.
Classification of Design Patterns
Design Patterns
Creational Behavioral
Structural
Creational Design Patterns
Creational Design Patterns focus on the process of object creation or problems
related to object creation. They help in making a system independent of how its objects
are created, composed, and represented. Creational patterns give a lot of flexibility in
what gets created, who creates it, and how it gets created. There are two main themes
in these patterns:
● They keep information about the specific classes used in the system hidden.
● They hide the details of how instances of these classes are created and
assembled.
Examples: Singleton, Factory Method, Abstract Factory, Builder patterns
Structural Design Patterns
Structural Design Patterns are solutions in software design that focus on how classes
and objects are organized to form larger, functional structures. These patterns help
developers simplify relationships between objects, making code more efficient, flexible,
and easy to maintain.
● This pattern is particularly useful for making independently developed class
libraries work together.
● Structural Design Patterns describe ways to compose objects to realize new
functionality.
Examples: Adapter, Composite, Proxy, Facade patterns
Behavioral Design Patterns
Behavioral design patterns are a category of design patterns that focus on the
interactions and communication between objects. They help define how objects
collaborate and distribute responsibility among them, making it easier to manage
complex control flow and communication in a system.
Examples: Chain of responsibility, Observer, State, Strategy patterns
Singleton Pattern
What is Singleton Pattern?
Singleton is a creational design pattern that lets you ensure that a class has only one
instance, while providing a global access point to this instance.
Properties of Singleton Pattern
1. Ensure that a class has just a single instance. Why would anyone want to control
how many instances a class has? The most common reason for this is to control
access to some shared resource.
Example: a database or a file.
1. Provide a global access point to that instance. Just like a global variable, the
Singleton pattern lets you access some object from anywhere in the program.
However, it also protects that instance from being overwritten by other code.
Real World Analogy
Imagine an office with 50 employees and one expensive printer. When anyone needs to
print, whether it's Sarah with her report, John with invoices, or Maria with a presentation.
They all send their documents to the same printer. Nobody creates a new printer each
time they need to print; everyone shares the one that already exists, saving money and
resources.
The Singleton pattern works exactly like the office printer: no matter how many times
employees ask for "the printer," they always get the same single shared instance rather
than creating wasteful duplicates.
Steps to Implement Singleton Pattern
Step 1: Make the default constructor private, to prevent other objects from using the
new operator with the Singleton class.
Step 2: Create a static creation method that acts as a constructor. Under the hood, this
method calls the private constructor to create an object and saves it in a static field. All
following calls to this method return the cached object.
Implementing the Singleton Pattern
When to Apply Singleton Pattern
1. Use the Singleton pattern when a class in your program should have
just a single instance available to all clients; for example, a single
database object shared by different parts of the program.
1. Use the Singleton pattern when you need stricter control over global
variables.
Factory Pattern
What is Factory Pattern?
Factory Pattern is a creational design pattern that provides an interface for creating
objects in a superclass, but allows subclasses to alter the type of objects that will be
created.
Problem Domain
Imagine that you’re creating a logistics management application. The first version of your app can
only handle transportation by trucks, so the bulk of your code lives inside the Truck class.
After a while, your app becomes pretty popular. Each day you receive dozens of requests from sea
transportation companies to incorporate sea logistics into the app.
Problem Domain
Great news, right? But how about the code? At present, most of your code is coupled to the Truck
class. Adding Ships into the app would require making changes to the entire codebase. Moreover, if
later you decide to add another type of transportation to the app, you will probably need to make all
of these changes again.
As a result, you will end up with pretty nasty code, riddled with conditionals that switch the app’s
behavior depending on the class of transportation objects.
Steps to Implement Factory Pattern
Step 1: Define an interface that all class categories/types will implement.
Step 2: Create concrete classes from the Interface.
Step 3: Create the Factory class.
Step 4: Clients should request for anything using the Factory class.
Factory Pattern Implementation
Factory Pattern Implementation
Factory Pattern Implementation
When to Apply Factory Pattern
1. Use the Factory Method when you don’t know beforehand the exact
types and dependencies of the objects your code should work with.
1. Use the Factory Method when you want to provide users of your library
or framework with a way to extend its internal components.
1. Use the Factory Method when you want to save system resources by
reusing existing objects instead of rebuilding them each time.