OOPS Principles (SOLID Principles):

Understanding SOLID Architecture Principles / Design / Styles

SOLID is an acronym for the first five object-oriented design (OOD) principles. 

It makes programmer life easy - used to write maintainable and extendible code.
Best suited for agile development.
 


Single Responsibility Principle (SRP)

Object or Entity should have only one responsibility.

  • The Single Responsibility Principle (SRP) states that a class should have only one reason to change
  • One Class should be responsible for one task.
  • The class itself is a single unit that must either be entirely used or not at all (discounting static methods and data for the moment).
  • If you can think of more than one motivation for changing a class, it probably has more than one responsibility.

Examples of Responsibilities:

  • Persistence
  • Validation
  • Notification
  • Error Handling
  • Logging
  • Class Selection / Instantiation
  • Formatting
  • Parsing
  • Mapping

 


Open Closed Principle (OCP)

Objects or Entities (classes, modules, methods/functions, etc.) should be Open for Extension, but Closed for Modification.

  • Entities behavior can be changed without the need to edit and recompile the code itself.
  • The Open-Closed Principle can also be achieved in many other ways, including through the use of inheritance or through compositional design patterns (e.g. Strategy pattern).

Example 1:

  • Create a Base class with Required functionality, and ensure we will not modify that class. (Closed for modification)
  • Create a Derived class by inheriting the Base class for extension (Open for modification)

 

  • public class BasicFileLogger : Logger
    Here we are extending/changing logger functionality using inheritance so that logger will have functionality related to file logging. Code Sample

 


Liskov Substitution Principle (LSP)

Let f(objMainClass) be a property provable about objects objMainClass of type MainClass. Then f(objSublass) should be provable for objects objSublass of type SubClass where SubClass is a subtype of MainClass.

The Liskov Substitution Principle (LSP) states that Liskov Substitution subtypes must be substitutable for their base types.

"Is-Substitutable-For" Not Just "Is-A" 

  • You should be able to substitute child types for their base types anywhere you need to work with them.
  • This means that you can write methods that accept a base type as a parameter, and they can work with that base type's methods and properties, regardless of what actual child implementation of that base class is passed as an argument. 

 
This principle is just an extension of the Open Close Principle. 
It means that we must make sure that new derived classes are extending the base classes without changing their behavior.


Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
 
 Or 
  
If any module is using a Base class then the reference to that Base class can be replaced with a Derived class without affecting the functionality of the module.
 

Or
 
While implementing derived classes, need to ensure that the derived classes just extend the functionality of base classes without replacing the functionality of base classes.

 

Reference Example


Interface Segregation Principle (ISP)

A client should never be forced to implement an interface that it doesn’t use

OR

clients shouldn’t be forced to depend on methods they do not use.

  • If a given interface has more features than you require, create a new interface that includes only the functionality that your client code requires, and which you can implement fully.
  • The Interface Segregation Principle (ISP) states that clients should not be forced to depend on methods that they do not use.

 

Don't Depend on What You Don't Use

Reference Example 


Dependency Inversion Principle (DIP)

  • Entities must depend on abstractions not on concretions.

  • It states that the high level module must not depend on the low level module, but they should depend on abstractions.

  • Abstractions should not depend on details. Details should depend upon abstractions.

By passing dependencies to classes as abstractions, you remove the need to program dependency specific. aka IoC (Inversion of Control) principle and implements as DI (Dependency Injection) pattern in the programming world.

Reference Example