0% found this document useful (0 votes)
61 views10 pages

SOLID Principles Explained with Examples

Uploaded by

huzaifamoin784
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views10 pages

SOLID Principles Explained with Examples

Uploaded by

huzaifamoin784
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

S: Single Responsibility Principle

Definition: A class should have only one reason to change.

Example: Separating user authentication and email notification.

public class UserAuth

public string Login(string username, string password)

// Authentication logic

return "User logged in";

public class EmailNotification

public string SendEmail(string email, string message)

// Email sending logic

return $"Email sent to {email}";

Each class has a single responsibility.


O: Open/Closed Principle

Definition: Classes should be open for extension but closed for modification.

Example: Adding new shapes without changing existing code.

public abstract class Shape

public abstract double Area();

public class Rectangle : Shape

public double Width { get; set; }

public double Height { get; set; }

public override double Area()

return Width * Height;

public class Circle : Shape

public double Radius { get; set; }

public override double Area()

return Math.PI * Radius * Radius;

}
// Usage

var shapes = new List<Shape>

new Rectangle { Width = 5, Height = 10 },

new Circle { Radius = 7 }

};

double totalArea = shapes.Sum(shape => shape.Area());

Console.WriteLine($"Total Area: {totalArea}");

Adding new shapes like Triangle doesn’t require modifying existing code.
L: Liskov Substitution Principle

Definition: Subtypes should be substitutable for their base types.

Example: A subclass should not break the behavior of its parent class.

public abstract class Bird

public abstract string Fly();

public class Sparrow : Bird

public override string Fly()

return "I am flying!";

public class Penguin : Bird // Violates Liskov because Penguins can't fly

public override string Fly()

throw new NotImplementedException("Penguins can't fly");

// Correct approach

public class NonFlyingBird : Bird

public override string Fly()


{

return "I can't fly";

// Usage

Bird penguin = new NonFlyingBird();

Console.WriteLine(penguin.Fly());
I: Interface Segregation Principle

Definition: A class should not be forced to implement methods it doesn’t use.

Example: Splitting a large interface into smaller ones.

public interface IPrinter

void Print();

public interface IScanner

void Scan();

public class AllInOnePrinter : IPrinter, IScanner

public void Print()

Console.WriteLine("Printing...");

public void Scan()

Console.WriteLine("Scanning...");

public class BasicPrinter : IPrinter


{

public void Print()

Console.WriteLine("Printing...");

A BasicPrinter only implements printing, not scanning.


D: Dependency Inversion Principle

Definition: High-level modules should not depend on low-level modules. Both should depend on
abstractions.

Example: Using abstraction for message delivery.

// The interface represents an abstraction for sending messages

public interface IMessageService

void SendMessage(string user, string message);

// Simple EmailService implementation

public class EmailService : IMessageService

public void SendMessage(string user, string message)

Console.WriteLine($"Email sent to {user}: {message}");

// Simple SMSService implementation

public class SMSService : IMessageService

public void SendMessage(string user, string message)

Console.WriteLine($"SMS sent to {user}: {message}");

}
// Notification class depends on the abstraction IMessageService

public class Notification

private readonly IMessageService _messageService;

// Constructor injection to provide the dependency

public Notification(IMessageService messageService)

_messageService = messageService;

// Notify method delegates message sending to the injected service

public void Notify(string user, string message)

_messageService.SendMessage(user, message);

// Usage Example

class Program

static void Main()

// Create EmailService and SMSService separately, and pass them to Notification

var emailNotification = new Notification(new EmailService());

emailNotification.Notify("[email protected]", "Hello via Email!");

var smsNotification = new Notification(new SMSService());

smsNotification.Notify("1234567890", "Hello via SMS!");


}

Key Simplifications:

Removed string returns: Instead of returning strings from SendMessage, I simplified it to just print
directly, making it easier to follow.

Constructor Injection: The Notification class still receives the IMessageService via constructor injection.
This keeps the code simple but still demonstrates the principle.

How Dependency Inversion Works Here:

Notification (high-level module) does not directly depend on EmailService or SMSService (low-level
modules).

Instead, it depends on the IMessageService interface, which is an abstraction.

We can easily switch out EmailService and SMSService without modifying Notification.

You might also like