SOLID: Single Responsibility Principle

Object Oriented Design Principles

A good design is most important step of Software Development life cycle, and to have a good design we must follow some set of guidelines. According to Robert Martin in “Agile Software Development: Principles, Patterns, and Practices” there are 3 main reasons of bad design that should be avoided:

  1. Rigidity – System is hard to change, because it affects many part of the system.
  2. Fragility – Change to a part affects an unexpected part of the system.
  3. Immobility – A module is hard to reuse in other System because it cannot be disentangled from the current System.

SOLID Principles

To solve these problems there is principle called SOLID. It consist of 5 components:

  1. S – Single Responsibility Principle
  2. O – Open Close Principle
  3. L – Liskov’s Substitution Principle
  4. – Interface Segregation Principle
  5. D – Dependency Inversion Principle

We will talk about each of them with example.

1. Single Responsibility Principle

A Class should have only one reason to change

Like we have a class for Report Management like this:

class Report {
  public void setTitle(String title) {
    // Set the title
  }
  
  public void setContent(String content) {
    // Set content
  }
  
  public String getTitle() {
    // return the title
  }
  
  public String getContent() {
    // return content
  }
  
  public void printReport() {
    // Print report
  }
}

At first it looks good, but this class can be change for two reason. First, the contents of report can change and second the printing logic can change. So these are two different responsibilities one is business logic and second one is representation logic and they must be separated according to SRP.

There are chances that if we change the business logic the representational logic will also change.

class Report {
  public void setTitle(String title) {
    // Set the title
  }
  
  public void setContent(String content) {
    // Set content
  }
  
  public String getTitle() {
    // return the title
  }
  
  public String getContent() {
    // return content
  }
}

interface PrintableReport {
  public void printReport(Report report);
}

// Different representation logics

class TextPrint implements PrintableReport {
  
  public void printReport(Report report) {
    System.out.print(report.getTitle() + report.getContent());
  }
}

class HTMLPrint implements PrintableReport {
  
  public void printReport(Report report) {
    System.out.print("<html><head><title>" + report.getTitle() + "</title></head><body>" + report.getContent() + "</body></html>");
  }
}

 

Now the Business logic and Representational logic are in different class. It will minimize the coupling and it is bad design to couple two different logics, also we can add new Representational logic easily without modifying our business logic. Now each class has only single responsibility.

This principle also helps to identify the classes of the system and designing class diagrams such that change in any functionality only affects the class diagram of classes responsible for that functionality (Reducing the rework).

 

Next: Open Close Principle

Leave a Reply