13-SOLID
Pragmatic Programmer Principles
Core Concept: Eliminate effects between unrelated components by designing them to be:
Self-contained
Independent
Having a single, well-defined purpose
Key Design Principles: SOLID
Purpose: SOLID is a set of principles aimed at improving software design and maintainability.
Key Principles:
Single Responsibility Principle (SRP)
Open/Closed Principle (OCP)
Liskov Substitution Principle (LSP)
Interface Segregation Principle (ISP)
Dependency Inversion Principle (DIP)
Understanding Abstraction
Definition: Abstraction is the high-level concept aimed at managing complexity.
Key Points:
Focuses on essential aspects for a given task and stakeholder.
Both excessive and insufficient abstraction can hinder understanding.
Facilitates discussion by aligning with individual stakeholder perspectives.
Decomposition
Definition: A mechanism for conceptualizing abstractions.
Objective: Break down complex descriptions into manageable parts.
Methodologies:
Can be approached both top down and bottom up.
Aim to simplify common tasks without limiting exceptional tasks.
Information Hiding
Definition: Refers to how programs utilize abstraction.
Functionality: Hides implementation details from higher-level interfaces.
Principles:
Separate variable elements from stable elements.
Differentiate between names and implementations (API vs. implementation).
Encapsulation
Definition: A language mechanism for implementing information hiding.
Characteristics:
Typically implemented through language interfaces.
Encompasses both data and behavior, separating them from their implementation details.
Abstraction vs. Encapsulation
Comparison:
Abstraction: Focuses on hiding unimportant details.
Encapsulation: Combines data and behavior to veil irrelevant details.
Integration: Encapsulation adds abstraction (e.g., creating a Cat class to encapsulate all cat behaviors).
Learning Outcomes
By the end of this lecture, you should be able to:
Evaluate SOLID principles in practice and identify adherence.
Identify principle violations and suggest refactorings to correct them.
Recognize interconnections among principles and their potential cascading violations.
Detailed Examination of SOLID Principles
Single Responsibility Principle (SRP)
Definition: A class should have only one responsibility.
Implication: Only one type of change in the system specification should affect the implementation of the class.
Violations: Divergent changes signal SRP violations, indicating a class is managing multiple responsibilities.
Example of SRP Violation
public class Employee {
// Determines how much an employee is paid
public calculatePay(): number;
// Stores Employee data in database
public save(): void;
// Reports hours worked and pay for auditing
public reportHours(): string;
}
Fixing SRP Violation
Each class should represent a single function with a single reason to change:
public class PayCalculator {
public calculatePay(emp: Employee): number;
}
public class EmployeeRepository {
public save(emp: Employee): void;
}
public class ReportGenerator {
public reportHours(emp: Employee): string;
}
Open/Closed Principle (OCP)
Definition: A class must be closed for modification but open for extension.
Design Implication: Base functionalities should remain unchanged while allowing extensions.
Strategy: Leverage inheritance or modular additions to implement new functionalities.
OCP Violation Example
If core class methods require overriding when specializing, it violates the OCP.
Improvement Example:
public init(): void {
// Implementation that loads configurations
}
Liskov Substitution Principle (LSP)
Definition: For any derived class to be substitutable for its base class, it must adhere to the properties of the base class.
Formula ( Type T and S hierarchy:**
Let ext{ϕ(x)} be a property for object x of type T.
Then ext{ϕ(y)} should hold for objects y of type S where S is a subtype of T.
Related Principle Aspects
Substitutability: Subclass should uphold the expectations set by its superclass.
Precondition Rule: Should not strengthen preconditions.
Postcondition Rule: Should not weaken postconditions.
Testing and LSP
Tests Requirement: Supertype black box tests must pass even when a subtype is substituted.
Form of Testing: For a class to be effectively substitutable for its superclass,
All the supertype tests should succeed on an instance of the subtype.
Summary of Liskov Substitution Principle
It emphasizes that objects of a superclass should be replaceable with objects of a subclass without altering the program's desirable properties. The integrity of behavior and outcome should remain consistent across derived classes, thereby facilitating maintainability, extensibility, and correct functionality throughout the codebase.