Single Responsibility Principle

Samyak Moon
3 min readJan 10, 2024

--

Introduction to Design Principles and Patterns

In this series of blogs, we’ll be learning various design principles and patterns. These are like the rules and blueprints that help us build better software. Understanding these principles is crucial because they help us in creating code that is easy to manage, scale and adapt.

In software world, design principles act as our guiding principles and patterns as our blueprints. They make sure our codebase is well structured, organized and ready for future changes and modifications.

In this blog, we will be learning about the first principle of SOLID design i.e. Single Responsibility principle.

Single Responsibility Principle (SRP)

It was said by Robert C. Martin that “A class must have only one reason to change”. To put it another way, each class should only have one task or responsibility.

Let’s consider an example of E-commerce application and how can be apply SRP in that. Let’s say we are building an e-commerce system, and we have a class namely ‘Order’.

The Order class is responsible for following functionalities

  1. Calculating total price.
  2. Managing the items in the order.
  3. Generating order confirmations and many more

Now, let’s say we also want an email notifications to customers when their orders are placed. Instead of adding the email-sending functionality directly into the Order class, we create a separate class called NotificationSender which will be responsible for sending email notifications.

By keeping these responsibilities separate, each class has a clear and distinct purpose. If any of the class needs any updates in future, let’s say in NotificationSender class we want to send an notification via email as well as sms then this modification can be done easily without affecting the Order class code.

This separation of classes makes code more modular, maintainable and easier to understand.

Now let’s understand this with the help of code.

Without SRP


import java.util.List;

class Item {
private String name;
private double price;

public Item(String name, double price) {
this.name = name;
this.price = price;
}
// getters and setters
}

class Order {
private List<Item> items;

public Order(List<Item> items) {
this.items = items;
}

public double calculateTotal() {
double total = 0;
for (Item item : items) {
total += item.getPrice();
}
return total;
}

public void generateOrderConfirmation() {
System.out.println("Order Confirmation: Order processed successfully!");
}

public void sendEmailNotification(String customerEmail) {
System.out.println("Email sent to " + customerEmail + ": Your order has been processed.");
}
}

public class ECommerceApp {
public static void main(String[] args) {

Item item1 = new Item("Laptop", 999.99);
Item item2 = new Item("Mouse", 19.99);

Order order = new Order(List.of(item1, item2));

double total = order.calculateTotal();
System.out.println("Total: Rs." + total);
order.generateOrderConfirmation();

order.sendEmailNotification("example.123@gmail.com");
}
}

In the above code we have put the notification method in Order class only. In future any change to the notification method or any addition related to notification will cause changes to Order class as well.

With SRP

import java.util.List;

class Item {
private String name;
private double price;

public Item(String name, double price) {
this.name = name;
this.price = price;
}

// Getters and setters
}

class Order {
private List<Item> items;

public Order(List<Item> items) {
this.items = items;
}

public double calculateTotal() {
double total = 0;
for (Item item : items) {
total += item.getPrice();
}
return total;
}

public void orderConfirmation() {
System.out.println("Order Confirmation: Order processed successfully!");
}
}

class NotificationSender {
public void sendEmailNotification(String customerEmail) {
System.out.println("Email sent to " + customerEmail + ": Your order has been processed.");
}
}

public class ECommerceApp {
public static void main(String[] args) {
Item item1 = new Item("Laptop", 999.99);
Item item2 = new Item("Mouse", 19.99);

Order order = new Order(List.of(item1, item2));

double total = order.calculateTotal();
System.out.println("Total: $" + total);
order.orderConfirmation();

NotificationSender notificationSender = new NotificationSender();
notificationSender.sendEmailNotification("example.123@gmail.com");
}
}

In this code, we have a new class called NotificationSender specifically for sending email notifications. This way, each class does one thing well. If we need to change how notifications work later or add any new notification method(like for sms), it won't change the Order class.

Conclusion

So, the Single Responsibility Principle is all about giving each class a clear task. This makes our code easier to manage and ready for any tweaks we might need down the road. Keep it simple, make it clean — that’s the power of SRP in Java!

--

--