In this tutorial, we will learn about single responsibility principle in java.It is one of SOLID principles and simplest design principle as well.
Single responsibility principle dictates that there should be only one reason to change the class.If you have more than one reason to change the class then refactor the class into multiple classes according to functionality.
We will understand with the help of a simple example.Let’s say you have Customer class as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
package org.arpit.java2blog; import java.util.List; public class Customer { String name; int age; long bill; List<Item> listsOfItems; Customer(String name,int age) { this.name=name; this.age=age; } // Calculate bill should not be responsibility of customer public long calculateBill(long tax) { for (Item item:listsOfItems) { bill+=item.getPrice(); } bill+=tax; this.setBill(bill); return bill; } //Report generation should not be responsibility of customer public void generateReport(String reportType) { if(reportType.equalsIgnoreCase("CSV")) { System.out.println("Generate CSV report"); } if(reportType.equalsIgnoreCase("XML")) { System.out.println("Generate XML report"); } } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public long getBill() { return bill; } public void setBill(long bill) { this.bill = bill; } public List<Item> getListsOfItems() { return listsOfItems; } public void setListsOfItems(List<Item> listsOfItems) { this.listsOfItems = listsOfItems; } } |
Do you see the problem with the above class? Let’ see what can be the issue with above class.
- If there is any change in the calculation of bill then we need to change Customer class.
- If you want to add one more report type to generate, then we need to change Customer class.
If you notice, calculation of bill and report generation should not be the responsibility of Customer, we should create different classes for these functionalities.
Let’s see refactored class now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package org.arpit.java2blog; import java.util.List; public class Customer { String name; int age; long bill; List listsOfItems; Customer(String name,int age) { this.name=name; this.age=age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public long getBill() { return bill; } public void setBill(long bill) { this.bill = bill; } public List getListsOfItems() { return listsOfItems; } public void setListsOfItems(List listsOfItems) { this.listsOfItems = listsOfItems; } } |
Create a new class named BillCalculator and pass Customer object to it.This class will be responsible for calculation of the customer bill
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package org.arpit.java2blog; import java.util.List; public class BillCalculator { public long calculateBill(Customer customer,long tax) { long bill=0; List listsOfItems=customer.getListsOfItems(); for (Item item:listsOfItems) { bill+=item.getPrice(); } bill+=tax; customer.setBill(bill); return bill; } } |
Create a new class named ReportGenerator and pass Customer object to it.This class will be responsible for generation of the customer report
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package org.arpit.java2blog; public class ReportGenerator { public void generateReport(Customer customer,String reportType) { // Extract data from customer object and generate the report if(reportType.equalsIgnoreCase("CSV")) { System.out.println("Generate CSV report"); } if(reportType.equalsIgnoreCase("XML")) { System.out.println("Generate XML report"); } } } |
As you can see now if we need to change anything in bill calculation, we don’t need to modify customer class, we will make changes in BillCalculator class.
Similarly, If you want to add another reporting type, then you need to make changes in ReportGenerator class rather than Customer class.
That’s all about Single Responsibility Principle in java.