Skip to content

Instantly share code, notes, and snippets.

@kumar-rajeswaran
Last active October 4, 2023 10:03
Show Gist options
  • Select an option

  • Save kumar-rajeswaran/5f3955d4ce6a4ed479eacf27982cb3ef to your computer and use it in GitHub Desktop.

Select an option

Save kumar-rajeswaran/5f3955d4ce6a4ed479eacf27982cb3ef to your computer and use it in GitHub Desktop.
SOLID in Software engineering
SOLID is an acronym representing five principles
that are intended to guide software design and make software
more understandable, flexible, and maintainable.
These principles are widely used in object-oriented programming,
and they form the foundation of good software design practices.
Single Responsibility Principle (SRP)
Problem:
A class that handles user authentication is also responsible for sending emails.
class AuthManager
{
public void AuthenticateUser(User user)
{
// Authentication logic
}
public void SendEmail(User user, string message)
{
// Email sending logic
}
}
Solution:
Separate the responsibilities into different classes.
class AuthManager
{
public void AuthenticateUser(User user)
{
// Authentication logic
}
}
class EmailSender
{
public void SendEmail(User user, string message)
{
// Email sending logic
}
}
Open/Closed Principle (OCP)
Problem:
An application has a class for calculating bonuses, but the logic needs to change for different types of employees.
class BonusCalculator
{
public double CalculateBonus(Employee employee)
{
// Bonus calculation logic
}
}
Solution:
Create an interface for bonus calculation and implement it for different employee types.
interface IBonusCalculator
{
double CalculateBonus(Employee employee);
}
class StandardBonusCalculator : IBonusCalculator
{
public double CalculateBonus(Employee employee)
{
// Standard bonus calculation logic
}
}
class SpecialBonusCalculator : IBonusCalculator
{
public double CalculateBonus(Employee employee)
{
// Special bonus calculation logic
}
}
Liskov Substitution Principle (LSP)
Problem:
Derived classes don't adhere to the behavior expected from the base class.
class Rectangle
{
public virtual void SetWidth(int width)
{
// Set width
}
public virtual void SetHeight(int height)
{
// Set height
}
}
class Square : Rectangle
{
public override void SetWidth(int width)
{
base.SetWidth(width);
base.SetHeight(width);
}
public override void SetHeight(int height)
{
base.SetHeight(height);
base.SetWidth(height);
}
}
Solution:
Refactor the design to adhere to the LSP.
class Shape
{
public virtual void SetDimensions(int width, int height)
{
// Set width and height
}
}
class Rectangle : Shape
{
public override void SetDimensions(int width, int height)
{
base.SetDimensions(width, height);
// Set specific dimensions for a rectangle
}
}
class Square : Shape
{
public override void SetDimensions(int width, int height)
{
if (width != height)
{
throw new InvalidOperationException("Width and height must be equal for a square.");
}
base.SetDimensions(width, height);
// Set specific dimensions for a square
}
}
Interface Segregation Principle (ISP)
Problem:
A class is forced to implement methods it doesn't need.
interface IWorker
{
void Work();
void Eat();
}
class Robot : IWorker
{
public void Work()
{
// Robot work logic
}
public void Eat()
{
// Robot can't eat, but forced to implement the method
}
}
Solution:
Split the interface into smaller, more specific interfaces.
interface IWorker
{
void Work();
}
interface IEater
{
void Eat();
}
class Robot : IWorker
{
public void Work()
{
// Robot work logic
}
}
Dependency Inversion Principle (DIP)
Problem:
High-level modules depend on low-level modules, causing high-level modules to be less flexible.
class DatabaseConnection
{
// Database connection logic
}
class UserManager
{
private DatabaseConnection _databaseConnection;
public UserManager()
{
_databaseConnection = new DatabaseConnection();
}
// UserManager logic using _databaseConnection
}
Solution:
Depend on abstractions (interfaces) rather than concrete implementations.
interface IDatabaseConnection
{
// Database connection methods
}
class DatabaseConnection : IDatabaseConnection
{
// Database connection logic
}
class UserManager
{
private IDatabaseConnection _databaseConnection;
public UserManager(IDatabaseConnection databaseConnection)
{
_databaseConnection = databaseConnection;
}
// UserManager logic using _databaseConnection
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment