Monday, October 9, 2023

Solid Priciples

SOLID principles allows object oriented programming implementation in an efficient better way into project development

     S-->Single Responsibility Principle  [SRP]

     O-->Open Closed Principle           [OCP]

     L-->Liskov Substitution Principle   [LSP]

     I-->Interface Segregation Principle [ISP]

     D-->Dependency Inversion Principle  [DIP]

S-Single Responsibility Principle

This means that every class or similar structure in your code should have only one job.

The class should be provided with single responsibility related to a particular task.

A module or class should have a very small piece of responsibility  in the entire application, This also reduces number of bugs and  improves development speed and most importantly makes developer’s  life lot easier

Example










It looks fine, but it is not following SRP. 

The SendEmailTo and ValidateEmailAddres methods have nothing to do with the UserService class. Let's refract it.

Let's refract it to satisfy SRP












O: Open/Closed Principle

Software entities (classes, modules) should be opened for extension, but closed for modification.

This principle suggests that the class should be easily extended but there is no need to change its core implementations.

Now, the below code violates OCP principle if the bank introduces a new Account  type. the code to be modified for adding a new account type.



      







We can apply OCP by using interface (or) abstract class when you want to      extend functionality will create a new class to each type of acct type customer 

   











Note:

when we need corporate acct type, we can create a new class by extending        interface without modifying exiting class[no modification] but extension

  







In the above code three new classes are created; Regularsavingaccount,  SalarySavingAccount, and CorporateAccount, by extending them from IAccount.

This solves the problem of modification of class and by extending interface,  we can extend functionality.

Above code is implementing both OCP and SRP principle, as each class has  single is doing a single task and we are not modifying class and only doing  an extension.

In C#, Open/Closed principle can be applied using the following approaches:

Using Function Parameters

Using Extension methods

Using Classes, Abstract class, or Interface-based Inheritance

Generics

By using Interface











Now, some developers want to change the Method DebugDetails, So to satisfy there needs you need to modify the Logger class and either create a new method for them or modify the existing DebugDetails() method. If you change the existing DebugDetails() method then the other developers who don't want this change will also be affected.

To solve this problem is to use class based-inheritance (polymorphism) 









Now, a new class can inherit the Logger class and change one or more method behavior











Liskov Substitution Principle[LSP]


Base classes must be able to use objects of derived classes without knowing it. LSP states that the child class should be perfectly substitutable for their parent class.

Base class var should be able to reference derived class object, it is called Upcasting principle

When you derived a class from a base class then the derived class should correctly implement all the methods of the base class. It should not remove some methods by throwing NotImplementedException.

LSP says that the derived class should correctly implement the base class methods.











To correct above implementation, we need to refactor this code by introducing interface with method called GetShape.

 


namespace Demo
{
 class Program
 {
 static void Main(string[] args)
 {
 Shape shape = new Circle();
 Console.WriteLine(shape.GetShape());
 shape = new Triangle ();
 Console.WriteLine(shape.GetShape());
 }
 }
 
 public abstract class Shape
 {
 public abstract string GetShape();
 }
 
 public class Triangle: Shape
 {
 public override string GetShape()
 {
 return "Triangle";
 }
 }
 
 public class Circle: Triangle
 {
 public override string GetShape()
 {
 return "Circle";
 }
 }
}









Output

Circle

Triangle


I-->Interface Segration Principle[ISP]

class should not be forced to implement methods which it does not need, and the contracts should be broken down to thin ones

[break one interface into different interfaces].

Using ISP, we can create separate interfaces for each operation or            requirement rather than having a single interface with so many methods.

Example








We can resolve this violation by dividing IOrder Interface.












D-->Dependency Inversion Principle  [DIP]

The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes


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

The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.

Refer Next Article of Mine to know more about Dependency Injection.





No comments:

Post a Comment

Thank you for visiting my blog

Kubernetes

Prerequisites We assume anyone who wants to understand Kubernetes should have an understating of how the Docker works, how the Docker images...