Practice
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Frontend UI Machine Coding
Resources
Career Advice and Roadmaps
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Backend Development
Frontend Development
Project Ideas for Software Developers
Core Computer Science
Companies
SDE Jobs & Internships
Interview Questions
Compare Companies
IDE
Online IDE
Collaborative IDE

Introduction to Software Design Patterns | Low Level Design (LLD)

Mayur Vaid
Mayur Vaid

There are various common problems that we might face while trying to design reusable, extensible and maintainable software. These problems are generally related to object creation, defining class structure, assignment of responsibilities between objects, enabling objects interaction without tightly coupling, etc.

To solve the recurring problems in software design, various patterns have been identified, tried, and tested over the years. Design Patterns are reusable solutions to recurring problems in software design. They help create software that are extensible, less complex, easy to understand, maintain, and, refactor.

Design Patterns are independent of programming languages and represent templates or descriptions for solving a particular design problem. Each design pattern solves a particular design problem. By studying the design patterns we can leverage the wisdom and lessons learned by experts over the years.

Types of Design Patterns

Creational Design Patterns

Creational Design Patterns deal with the way classes are instantiated and objects are created. These design patterns are used when there is a specific requirements related to creating objects.

Let us look at a design problem related to object creation.

Example

Let's say that we have a class named Dog that implements the Animal interface. We can create an object of the Dog class like this:

Dog dog = new Dog();

Let's say that there are multiple classes that implement the Animal class.

If the use case requires having our code run on different Animal objects irrespective of the concrete class, the above code might create issues. Here, we are creating the dog object by instantiating the Dog class directly.

We should instead be abstracting the object creation process. Here, we can use the Factory Method Design Pattern which is one of the creational design patterns.

Factory Method:

Animal initializeAnimal(String type) {
	if(type.equals("Dog")) {
		return new Dog();
	} else if(type.equals("Cat")) {
		return new Cat();
	} else if(type.equals("Monkey")) {
		return new Monkey();
	}
	throw new Error("Invalid Animal Type");
}

Initialization:

Animal animal = initializeAnimal(animalType);

There can be other design problems related to object creation as well based on our design requirements. We may want to use one of the creational design patterns based on the use case.

We will learn about the Creational Design Patterns in further articles.

Structural Design Patterns

Structural Design Patterns deal with how objects and classes can be composed or assembled together to form a larger structure or subsystem that can offer some additional specific functionality. They help assemble the classes and make sure that the structure is extensible and reusable.

Let us look at a design problem related to structuring classes.

Example

Let’s say there is a class JSONGraphPlotter with a function plot(data) that can plot beautiful graphs based on JSON data.

Let's say that we have a use case of creating graphs based on XML data. We can do that by creating a class that converts XML to JSON and then calling JSONGraphPlotter.plot. Instead of providing the responsibility of using the two classes to the client, we should be creating an abstraction, i.e., a single interface that allows doing both through a single function call.

Here we can use the Adapter Design Pattern. We will have an Adapter class XMLGraphPlotter that exposes a method plot which takes XML data as parameter. The XMLGraphPlotter.plot method would internally transform the XML data into JSON and call the JSONGraphPlotter.plot method with the JSON data. The client can work with the XMLGraphPlotter class to plot graphs with XML data without any change required in the JSONGraphPlotter class.

There can be other design problems related to class structuring as well based on our design requirements. We may want to use one of the structural design patterns based on the use case.

We will learn about the Structural Design Patterns in further articles.

Behavioral Design Patterns

Behavioral design patterns deal with the assignment of responsibilities and communication between objects. It focuses on how the objects can interact or communicate with each other while still being loosely coupled.

Let us look at a design problem related to behavior of objects.

Example

Let's say we want to design a Parking Lot. The Parking Lot service should assign a vacant parking slot to any vehicle that wants to park.

The algorithm to assign a free parking spot to a vehicle may vary based on different criteria. There can be new requirements as well based on which the algorithm to assign a vacant parking spot to a vehicle may vary.

Instead of putting conditionals everywhere in our code, we can apply the Strategy Design Pattern. This pattern allows us to switch the behavior between a family of algorithms during runtime. We can create different Strategy classes based on the same interface. Each strategy class would be used to implement a different algorithm. The clients would be able to pass any strategy as required.

There can be other design problems related to the behavior of an object or communication between the objects as well based on our design requirements. We may want to use one of the behavioral design patterns based on the use case.

We will learn about the Behavioral Design Patterns in further articles.


I hope that you found this tutorial helpful. We will be creating more such tutorials on Design Patterns and Low-Level Design in the near future. Please support us by sharing this article with your friends on Whatsapp and on social media.

1
Mayur Vaid
Mayur Vaid
Mayur is SDE @ Flipkart. He is trying to prepare and share content on his Youtube channel that can help anyone prepare for getting into top tech firms.
SDE Bootcamp - Become a software engineer at a product-based company
Practice Machine Coding
Learning Resources
Interview Prep Resources
Blog
  • Career Advice and Roadmaps
  • Data Structures & Algorithms
  • Machine Coding Round (LLD)
  • System Design & Architecture
  • Backend Development
  • Frontend Development
  • Awesome Project Ideas
  • Core Computer Science
Practice Questions
  • Machine Coding (LLD) Questions
  • System Design (HLD) Questions
  • Topic-wise DSA Questions
  • Company-wise DSA Questions
  • DSA Sheets (Curated Lists)
  • JavaScript Interview Questions
  • Frontend UI Machine Coding Questions
Online Compilers (IDE)
  • Online Java Compiler
  • Online C++ Compiler
  • Online C Compiler
  • Online Python Compiler
  • Online JavaScript Compiler
Topic-wise Problems
  • Dynamic Programming Interview Questions
  • Linked List Interview Questions
  • Graph Interview Questions
  • Backtracking Interview Questions
  • Arrays Interview Questions
  • Trees Interview Questions
Company-wise Problems
  • Amazon Interview Questions
  • Microsoft Interview Questions
  • Google Interview Questions
  • Flipkart Interview Questions
  • Adobe Interview Questions
  • Facebook Interview Questions
DSA Sheets (Curated Lists)
  • Top Interview Questions
  • FAANG Interview Questions
  • Most Asked Interview Questions
  • 6 month DSA Practice Sheet
  • 3 month DSA Practice Sheet
  • Last minute DSA Practice Sheet