Solid overview

From bibbleWiki
Jump to navigation Jump to search

Introduction

  • SRP Single Responsibility Principle
  • OCP Open Closed Principle
  • LSP Liskov Substitution Principle
  • ISP Interface Segregation Principle
  • DIP Dependency Inversion Principle

SRP Single Responsibility Principle

Each software module should have one and only one reason to change

Coupling cohesion.png

Cohesion

This refers to what a class or module can do. When a class has low cohesion, it means that it does a great variety of actions and in that, the class is unfocused on what it should do. High cohesion means that the class is focused on what it should be doing as it contains only methods relating to the intention of the class.

Coupling

This refers to how related or dependent two classes or modules are towards each other. For low coupled classes, a major change in one class has a low impact on the other. High coupling in a system makes it difficult to maintain since a change in one class will have impact on other classes as well. This could result in one change flowing through a system as an oil slick, sometimes even requiring a full overhaul to fully implement.

Examples of Responsibilities

In software, some examples of responsibilities that may need to be separated are the following:

  • Notification
  • Error handling
  • Logging
  • Formatting
  • Parsing
  • Persistence
  • Validation

OCP Open Closed Principle

Software Entities (classes, modules, function etc.) should be open for extension, but closed for modification
Typical approaches to OCP is

  • Parameters
  • Inheritance
  • Composition/Injection

A very simple example of this concept would be an old photo camera that does not allow changing of lenses. It is not open for extension and thus violates the OCP. Most modern SLR cameras have interchangeable lenses and by that extending the functionality to achieve different photographic results with different lenses. Moreover, changing a lens does not modify the camera's basic functionality to take photo's.

  • Solve the problem first using concrete code
  • Identify the kinds of changes the app is likely to continue to need
  • Modify the code to be extensible

LSP Liskov Substitution Principle

Subtypes must be substitutable for their base types

  • Subtypes must be substitutable for their base types
  • Ensure the base type invariants are enforced
  • Check for, Type checking, null checking and Not Implemented Exception

When this Liskov substitution principle is violated, it tends to result in a lot of extra conditional logic scattered throughout the application. This duplicate, scattered code becomes a breeding ground for bugs as the application grows. A common code smell that is often an indication of a LSP violation is the presence of type checking code within a code block that should be polymorphic.

ISP Interface Segregation Principle

Client should not be forced to depend on methods they do not use
Only make the user implement whichever methods they intent to use. This problem is commonly found in interfaces. An interface is a collection of functions that have a name and defined input and output parameters, but no implementation. A class implementing this interface needs to implement all functions in the interface.

  • Prefer small, cohesive interface to large
  • Following ISP helps with SRP and LSP
  • Break up large interfaces by using
    • Interface inhertiance
    • The Adapter design pattern

DIP Dependency Inversion Principle

High level modules should not depend on low level modules; both should depend on abstractions
Abstractions should not depend on details, the details should depend on the abstractions

  • Most classes should depend on abstractions, not implementation details
  • Classes should be explicit about their dependencies
  • Client should inject dependencies when they create other classes
  • Structure your solutions to leverage dependency inversion

Summary

Solid summary.png