Single Responsibility Principle (SRP)

A class should have one, and only one, reason to change

The Single Responsibility Principle

Example

Bad
Example of SRP violation
Good
Example of design following SRP

Another Example

Bad
Example of SRP violation
Good
Example of design following SRP

Identifying Responsibilities Can be Tricky

Eg

Open Closed Principle (OCP)

Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification

Conforming to OCP

Example

Bad
Bad Example
void incAll(Employee[] emps) {
    for (int i = 0; i < emps.size(); i++) {
        if (emps[i].empType == FACULTY)
            incFacultySalary((Faculty)emps[i]);
        else if (emps[i].empType == STAFF)
            incStaffSalary((Staff)emps[i]);
        else if (emps[i].empType == SECRETARY)
            incSecretarySalary((Secretary)emps[i]);
    }
}
Good
Better Example
void incAll(Employee[] emps) {
    for (int i = 0; i < emps.size(); i++) 
        emps[i].incSalary(); 
}

Abstraction is the Key

Eg

Anticipating Future Changes

Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their base type

Liskov Substitution Principle

Subtyping VS Implementation Inheritance

The Liskov Substitution Principle and Reuse

Eg

Violation of LSP may lead to another violation

void f(PType x) {
    // some code misbevaves when x is Ctype
    …
}
void f(PType x) {
    if (x instanceof( Ctype)) throw new RuntimeException();
    // some code misbevaves when x is Ctype
    …
}

Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions

Eg
Typical in Structured Analysis & Design
Eg
Dependency Inversion Principle

Inversion of Ownership

The dependency inversion principle

Bad
Good

Interface Segregation Principle (ISP)

Clients should not be forced to depend on methods they do not use

Fat interface

Example

Bad
Original Design
Good
Better Design