0% found this document useful (0 votes)
15 views42 pages

C# Conce

Uploaded by

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

C# Conce

Uploaded by

musabinshabeer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 42

C# Concepts

SOLID Principles
C#: Solid Principles

• SOLID Principles SOLID is an acronym representing five


fundamental design principles in object-oriented
programming (OOP) that aim to create more
maintainable, understandable, and flexible software.
• These principles were introduced by Robert C. Martin
(Uncle Bob) and are widely regarded as best practices in
software development.
C#: Solid Principles

• Single Responsibility Principle (SRP): Classes should have


one reason to change. By injecting dependencies, each class
focuses on its primary responsibility.
• Open/Closed Principle (OCP): Classes should be open for
extension but closed for modification. DI facilitates this by
allowing new implementations to be introduced without altering
existing classes.
• Liskov Substitution Principle (LSP): Objects of a superclass
should be replaceable with objects of a subclass. DI ensures that
classes depend on abstractions, making substitution seamless.
C#: Solid Principles

• Interface Segregation Principle (ISP): No client


should be forced to depend on methods it does not
use. Using interfaces with DI ensures that classes
only depend on the interfaces they need.
• Dependency Inversion Principle (DIP): High-level
modules should not depend on low-level modules; both
should depend on abstractions. DI is a direct
implementation of DIP.
Solid Principles: Single
Responsibility Principle (SRP)

• Definition: A class should have only one reason to


change, meaning it should have only one job or
responsibility.
• Explanation:
• By ensuring that a class handles a single responsibility,
you make your code easier to maintain and understand.
• If a class has multiple responsibilities, changes in one
responsibility might affect others, leading to bugs and
increased complexity.
Single Responsibility Principle –
Example: Violation of SRP

public class Report


{
public void GenerateReport()
{
// Code to generate report
}
Single Responsibility Principle –
Example: Violation of SRP
public void SaveToFile(string path)
{
// Code to save report to file
}

public void SendByEmail(string email)


{
// Code to send report via email
}
}
Single Responsibility Principle –
Example: Refactored With SRP

public class ReportGenerator


{
public void GenerateReport()
{
// Code to generate report
}
}
Single Responsibility Principle –
Example: Refactored With SRP

public class ReportSaver


{
public void SaveToFile(Report report, string
path)
{
// Code to save report to file
}
}
Single Responsibility Principle –
Example: Refactored With SRP

public class ReportEmailer


{
public void SendByEmail(Report report, string
email)
{
// Code to send report via email
}
}
Solid Principles: Single
Responsibility Principle (SRP) -
Benefits
• Maintainability: Easier to modify individual
responsibilities.

• Testability: Each class can be tested


independently.

• Reusability: Classes with single responsibilities are


more reusable across different contexts.
Solid Principles: Open/Closed
Principle (OCP)

• Definition: Software entities (classes, modules,


functions, etc.) should be open for extension but
closed for modification.
• Explanation:
• One should be able to add new functionality to a
class without altering its existing code.
• This reduces the risk of introducing bugs into
existing functionality when adding new features.
Open/Closed Principle– Example:
Violation of OCP

public class Rectangle


{
public double Width { get; set; }
public double Height { get; set; }
}
Open/Closed Principle– Example:
Violation of OCP
public class AreaCalculator
{
public double CalculateArea(object shape)
{
if (shape is Rectangle rect)
{
return rect.Width * rect.Height;
}
throw new ArgumentException("Unknown
shape");
}
Open/Closed Principle– Example:
Refactored of OCP

public interface IShape


{
double CalculateArea();
}
Open/Closed Principle– Example:
Refactored of OCP
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }

public double CalculateArea()


{
return Width * Height;
}
}
Open/Closed Principle– Example:
Refactored of OCP
public class Circle : IShape
{
public double Radius { get; set; }

public double CalculateArea()


{
return Math.PI * Radius * Radius;
}
}
Open/Closed Principle– Example:
Refactored of OCP
public class AreaCalculator
{
public double CalculateArea(IShape shape)
{
return shape.CalculateArea();
}
}
Solid Principles: Open/Closed
Principle (OCP) - Benefits

• Extensibility: Easily add new shapes without


modifying existing AreaCalculator.

• Maintainability: Reduces risk when introducing


new features.

• Encapsulation: Each shape knows how to calculate


its own area.
Solid Principles: Liskov Substitution
Principle (LSP)

• Definition: Objects of a superclass should be


replaceable with objects of a subclass without
affecting the correctness of the program.
• Explanation:
• Subclasses should extend the base classes without
changing their behavior.
• This ensures that the derived classes can stand in
for their base classes seamlessly.
Liskov Substitution Principle –
Example: Violation of LSP
public class Bird
{
public virtual void Fly()
{
Console.WriteLine("Flying");
}
}
Liskov Substitution Principle –
Example: Violation of LSP
public class Ostrich : Bird
{
public override void Fly()
{
throw new
NotImplementedException("Ostriches
can’t fly");
}
}
Liskov Substitution Principle –
Example: Refactored of LSP
public interface IBird
{
void Eat();
}

public interface IFlyingBird : IBird


{
void Fly();
}
Liskov Substitution Principle –
Example: Refactored of LSP
public class Sparrow : IFlyingBird
{
public void Eat()
{
Console.WriteLine("Sparrow eating");
}

public void Fly()


{
Console.WriteLine("Sparrow flying");
}
Liskov Substitution Principle –
Example: Refactored of LSP
public class Ostrich : IBird
{
public void Eat()
{
Console.WriteLine("Ostrich eating");
}
}
Solid Principles: Liskov Substitution
Principle (LSP) - Benefits

• Polymorphism: Subclasses can be used


interchangeably with their base interfaces.

• Robustness: Prevents unexpected behaviors when


using subclasses.

• Clear Contracts: Interfaces define clear


capabilities of classes.
Solid Principles: Interface
Segregation Principle (ISP)

• Definition: Clients should not be forced to depend on


interfaces they do not use. Instead of having large,
"fat" interfaces, it's better to have smaller, more
specific ones.
• Explanation:
• Breaking down interfaces into smaller, cohesive ones
prevents implementing classes from being burdened
with unnecessary methods, promoting cleaner and
more understandable code.
Interface Segregation Principle –
Example: Violation of ISP
public interface IMultiFunctionDevice
{
void Print(Document doc);
void Scan(Document doc);
void Fax(Document doc);
}
Interface Segregation Principle –
Example: Violation of ISP
ppublic class OldPrinter : IMultiFunctionDevice
{
public void Print(Document doc)
{
// Printing logic
}

public void Scan(Document doc)


{
throw new NotImplementedException();
}
Interface Segregation Principle –
Example: Violation of ISP

public void Fax(Document doc)


{
throw new NotImplementedException();
}
}
Interface Segregation Principle –
Example: Refactored of ISP
public interface IPrinter
{
void Print(Document doc);
}

public interface IScanner


{
void Scan(Document doc);
}
Interface Segregation Principle –
Example: Refactored of ISP
public interface IFax
{
void Fax(Document doc);
}

public class Printer : IPrinter


{
public void Print(Document doc)
{
// Printing logic
}
Interface Segregation Principle –
Example: Refactored of ISP
public class MultiFunctionPrinter : IPrinter, IScanner, IFax
{
public void Print(Document doc)
{
// Printing logic
}

public void Scan(Document doc)


{
// Scanning logic
}
Interface Segregation Principle –
Example: Refactored of ISP

public void Fax(Document doc)


{
// Faxing logic
}
}
Solid Principles: Interface
Segregation Principle (ISP) - Benefits

• Flexibility: Classes can implement only the


interfaces they need.

• Maintainability: Easier to manage and extend


interfaces.

• Clarity: Interfaces define clear, specific contracts.


Solid Principles: Dependency
Inversion Principle (DIP)

• Definition: High-level modules should not depend on


low-level modules. Both should depend on
abstractions (e.g., interfaces). Additionally,
abstractions should not depend on details; details
should depend on abstractions.
• Explanation:
• By depending on abstractions rather than concrete
implementations, you promote loose coupling and
enhance the flexibility and testability of your code.
Dependency Inversion Principle –
Example: Violation of DIP
public class EmailService
{
public void SendEmail(string message)
{
// Send email logic
}
}
Dependency Inversion Principle –
Example: Violation of DIP

public class Notification


{
private EmailService _emailService = new
EmailService();

public void Notify(string message)


{
_emailService.SendEmail(message);
}
}
Dependency Inversion Principle –
Example: Refactored of DIP

public interface IMessageService


{
void SendMessage(string message);
}
Dependency Inversion Principle –
Example: Refactored of DIP
public class EmailService : IMessageService
{
public void SendMessage(string message)
{
// Send email logic
}
}

public class SMSService : IMessageService


{
public void SendMessage(string message)
{
// Send SMS logic
}
Dependency Inversion Principle –
Example: Refactored of DIP
public class Notification
{
private readonly IMessageService _messageService;

public Notification(IMessageService messageService)


{
_messageService = messageService;
}

public void Notify(string message)


{
_messageService.SendMessage(message);
}
Solid Principles: Dependency
Inversion Principle (DIP) - Benefits

• Loose Coupling: Notification depends on the


IMessageService abstraction, not the concrete
EmailService.

• Flexibility: Easily switch between different


IMessageService implementations.

• Testability: Mock IMessageService for unit testing


Notification.

You might also like