DEV Community

Anil Singh
Anil Singh

Posted on

SOLID Principles C# with real-time Example

The SOLID principles, the rock stars of object-oriented design! Let's break them down:

Image description

S - Single Responsibility Principle (SRP): A class should have only one reason to change, meaning it should have only one responsibility.

O - Open/Closed Principle (OCP): Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. In other words, you should be able to add new functionality without altering existing code.

L - Liskov Substitution Principle (LSP): Subtypes must be substitutable for their base types without altering the correctness of the program. This ensures that objects of a superclass should be able to be replaced with objects of a subclass without affecting the functionality.

I - Interface Segregation Principle (ISP): A class should not be forced to implement interfaces it does not use. In simpler terms, clients should not be forced to depend on interfaces they do not use.

D - Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules; both should depend on abstractions. This principle encourages the use of interfaces or abstract classes to decouple high-level and low-level modules.

The 5 principles of SOLID are:

  1. Single Responsibility Principle (SRP)
  2. Open-Closed Principle (OCP)
  3. Liskov Substitution Principle (LSP)
  4. Interface Segregation Principle (ISP)
  5. DependencyInversion Principle (DIP)

These principles provide a guide to writing clean, maintainable, and scalable code in object-oriented systems.

Top comments (1)

Collapse
 
anilsingh profile image
Anil Singh

Absolutely, let's go with a C# example:

1. Single Responsibility Principle (SRP):

// Not following SRP
public class Shape
{
public void Draw()
{
// Drawing logic
}

public double CalculateArea()
{
    // Area calculation logic
    return 0.0;
}
Enter fullscreen mode Exit fullscreen mode

}

// Following SRP
public class Shape
{
public void Draw()
{
// Drawing logic
}
}

public class Calculator
{
public double CalculateArea(Shape shape)
{
// Area calculation logic
return 0.0;
}
}

2. Open/Closed Principle (OCP):

// Not following OCP
public class Circle
{
public void Draw()
{
// Drawing logic
}

public double CalculateArea()
{
    // Area calculation logic
    return 0.0;
}

public double CalculateVolume()
{
    // Volume calculation logic, violating OCP
    return 0.0;
}
Enter fullscreen mode Exit fullscreen mode

}

// Following OCP
public abstract class Shape
{
public abstract void Draw();
public abstract double CalculateArea();
}

public class Circle : Shape
{
public override void Draw()
{
// Drawing logic
}

public override double CalculateArea()
{
    // Area calculation logic
    return 0.0;
}
Enter fullscreen mode Exit fullscreen mode

}

public class Cylinder : Shape
{
public override void Draw()
{
// Drawing logic
}

public override double CalculateArea()
{
    // Area calculation logic
    return 0.0;
}

public double CalculateVolume()
{
    // Volume calculation logic
    return 0.0;
}
Enter fullscreen mode Exit fullscreen mode

}

3. Liskov Substitution Principle (LSP):

// Not following LSP
public class Bird
{
public void Fly()
{
// Flying logic
}
}

public class Ostrich : Bird
{
public new void Fly()
{
throw new Exception("I can't fly!"); // Violates LSP
}
}

// Following LSP
public class Bird
{
public virtual void Move()
{
// Moving logic
}
}

public class Sparrow : Bird
{
public override void Move()
{
// Flying logic
}
}

public class Ostrich : Bird
{
public override void Move()
{
// Walking logic
}
}

*4. Interface Segregation Principle (ISP):
*

// Not following ISP
public interface IWorker
{
void Work();
void Eat();
}

public class Worker : IWorker
{
public void Work()
{
// Work logic
}

public void Eat()
{
    // Eat logic
}
Enter fullscreen mode Exit fullscreen mode

}

// Following ISP
public interface IWorkable
{
void Work();
}

public interface IEatable
{
void Eat();
}

public class Worker : IWorkable, IEatable
{
public void Work()
{
// Work logic
}

public void Eat()
{
    // Eat logic
}
Enter fullscreen mode Exit fullscreen mode

}

5. Dependency Inversion Principle (DIP):

// Not following DIP
public class LightBulb
{
public void TurnOn()
{
// Turn on logic
}

public void TurnOff()
{
    // Turn off logic
}
Enter fullscreen mode Exit fullscreen mode

}

public class Switch
{
public void Operate(LightBulb bulb)
{
if (bulb.State == "on")
{
bulb.TurnOff();
}
else
{
bulb.TurnOn();
}
}
}

// Following DIP
public interface ISwitchable
{
void TurnOn();
void TurnOff();
}

public class LightBulb : ISwitchable
{
public void TurnOn()
{
// Turn on logic
}

public void TurnOff()
{
    // Turn off logic
}
Enter fullscreen mode Exit fullscreen mode

}

public class Switch
{
public void Operate(ISwitchable device)
{
if (device.State == "on")
{
device.TurnOff();
}
else
{
device.TurnOn();
}
}
}

These C# examples should give you a practical understanding of how SOLID principles can be implemented in object-oriented programming.