SOLID Principles
Mohd Saeed
Technical Lead @ Capital Numbers | Application Developer | .Net Core | C# | Web API | Entity Framework Core | Type Script | JavaScript | SQL | GIT | Docker
The SOLID principles are a set of five design principles for writing maintainable, scalable, and robust object-oriented software.
1) Single Responsibility Principle (SRP):
The Single Responsibility Principle (SRP) is a design principle in object-oriented programming that states that a class should have only one reason to change, meaning it should have only one responsibility or job. In simpler terms, it suggests that a class should encapsulate one and only one aspect of functionality, and that aspect should be entirely encapsulated by the class.
Example:
// Bad design (violates SRP)
class Customer
{
public void AddCustomer() { /* code for adding a customer */ }
public void GenerateInvoice() { /* code for generating an invoice */ }
public void SendEmail() { /* code for sending an email */ }
}
// Good design (adheres to SRP)
class Customer
{
public void AddCustomer() { /* code for adding a customer */ }
}
class InvoiceGenerator
{
public void GenerateInvoice() { /* code for generating an invoice */ }
}
class EmailSender
{
public void SendEmail() { /* code for sending an email */ }
}
2) Open/Closed Principle (OCP):
Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
In simpler terms, it means that the behavior of a module should be extendable without modifying its source code. This is typically achieved through the use of abstraction and polymorphism.
Here's what it entails:
Example:
// Bad example - violating OCP
class Circle
{
public double Radius { get; set; }
}
class AreaCalculator
{
public double CalculateArea(Circle circle)
{
return Math.PI * Math.Pow(circle.Radius, 2);
}
// Later requirement to calculate the area of a rectangle
public double CalculateArea(Rectangle rectangle)
{
return rectangle.Width * rectangle.Height;
}
}
// Good example - adhering to OCP
interface IShape
{
double CalculateArea();
}
class Circle : IShape
{
public double Radius { get; set; }
public double CalculateArea()
{
return Math.PI * Math.Pow(Radius, 2);
}
}
class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double CalculateArea()
{
return Width * Height;
}
}
3) Liskov Substitution Principle (LSP):
The principle states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program. In other words, a subclass should be substitutable for its superclass without altering the desirable properties of the program, such as correctness, performance, and behavior.
领英推荐
Example:
// Bad example - violating LSP
class Rectangle
{
public virtual double Width { get; set; }
public virtual double Height { get; set; }
}
class Square : Rectangle
{
public override double Width
{
get => base.Width;
set
{
base.Width = value;
base.Height = value;
}
}
public override double Height
{
get => base.Height;
set
{
base.Width = value;
base.Height = value;
}
}
}
// Good example - adhering to LSP
abstract class Shape
{
public abstract double Area { get; }
}
class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area => Width * Height;
}
class Square : Shape
{
public double Side { get; set; }
public override double Area => Side * Side;
}
4) Interface Segregation Principle (ISP):
According to the ISP, a client should not be forced to implement interfaces that it doesn't use. In other words, instead of creating large interfaces that contain methods for multiple functionalities, it's better to have smaller, more specialized interfaces that are tailored to specific client needs. This helps in reducing the coupling between classes and promotes a more modular and cohesive design.
Example:
// Bad example - violating ISP
interface IShape
{
void Draw();
void Resize();
void Rotate();
}
class Circle : IShape
{
public void Draw()
{
// Code to draw a circle
}
public void Resize()
{
// Code to resize a circle
}
public void Rotate()
{
// Code to rotate a circle
}
}
// Good example - adhering to ISP
interface IDrawable
{
void Draw();
}
interface IResizable
{
void Resize();
}
interface IRotatable
{
void Rotate();
}
class Circle : IDrawable, IResizable
{
public void Draw()
{
// Code to draw a circle
}
public void Resize()
{
// Code to resize a circle
}
}
5) Dependency Inversion Principle (DIP):
The Dependency Inversion Principle (DIP) is one of the five SOLID principles of object-oriented programming (OOP), which aims to create systems that are easier to maintain and extend.
In simpler terms, this principle suggests that rather than depending on concrete implementations, modules and classes should rely on abstract interfaces or classes. This abstraction helps to decouple components within a system, making it easier to replace, modify, and extend them without affecting the rest of the system.
Example:
// Bad example - violating DIP
class DataAccessLayer
{
public void SaveData(object data)
{
// Code to save data to a database
}
}
class BusinessLogicLayer
{
private DataAccessLayer dataAccessLayer;
public BusinessLogicLayer()
{
dataAccessLayer = new DataAccessLayer();
}
public void ProcessData(object data)
{
// Code to process data
dataAccessLayer.SaveData(data);
}
}
// Good example - adhering to DIP
interface IDataAccessLayer
{
void SaveData(object data);
}
class DataAccessLayer : IDataAccessLayer
{
public void SaveData(object data)
{
// Code to save data to a database
}
}
class BusinessLogicLayer
{
private IDataAccessLayer dataAccessLayer;
public BusinessLogicLayer(IDataAccessLayer dataAccessLayer)
{
this.dataAccessLayer = dataAccessLayer;
}
public void ProcessData(object data)
{
// Code to process data
dataAccessLayer.SaveData(data);
}
}
These examples demonstrate how the SOLID principles can be applied in C# to improve the design and maintainability of your code. Remember that applying these principles can lead to more flexible and easier-to-maintain software architectures.
Senior Software Engineer @ AlsoEnergy
7 个月Well said