In modern software development, writing clean, maintainable, and scalable code is as important as delivering functionality. This is where SOLID principles play a crucial role. Introduced by Robert C. Martin (Uncle Bob), SOLID represents a set of five design principles that guide developers to create software that is easy to understand, modify, and extend without breaking existing functionality.
In this article, we’ll explore each SOLID principle with real-time examples in .NET Core, C#, and Angular applications.
1. Single Responsibility Principle (SRP)
Definition: A class should have only one reason to change, meaning it should do only one job.
Example:
Suppose you have a class InvoiceManager
handling both invoice creation and sending email notifications.
👉 This violates SRP because the class handles two responsibilities.
Refactored:
Now, InvoiceManager
only deals with invoices, and EmailService
manages emails.
Real-Time Example:
In an e-commerce application, the order processing service should only handle order logic, while a separate service should handle notifications.
2. Open/Closed Principle (OCP)
Definition: Software entities (classes, modules, functions) should be open for extension but closed for modification.
Example:
Imagine you have a PaymentProcessor
class supporting Credit Card payments. Later, you need to add UPI payments.
❌ Bad approach – modifying the existing class:
👉 This violates OCP because every new payment method requires changing the class.
✅ Better approach – use abstraction:
Now, you can add new payment methods without modifying the PaymentProcessor
.
Real-Time Example:
A food delivery app can add new payment gateways (PayPal, Wallets, UPI, etc.) without modifying the existing payment processing logic.
3. Liskov Substitution Principle (LSP)
Definition: Objects of a superclass should be replaceable with objects of its subclasses without breaking the application.
Example:
Suppose you have a base class Bird
with a method Fly()
.
👉 Here, Ostrich
violates LSP because an ostrich cannot fly. This breaks the substitution principle.
✅ Better approach:
Now, the hierarchy respects LSP.
Real-Time Example:
In a transport booking system, a Car
and a Bike
can be substituted for a Vehicle
, but a Flight
may need a different interface since it doesn’t behave the same way on roads.
4. Interface Segregation Principle (ISP)
Definition: A client should not be forced to implement methods it does not use.
Example:
👉 If a basic printer only supports printing, it will still be forced to implement Scan()
and Fax()
unnecessarily.
✅ Better approach:
Real-Time Example:
In an employee management system, not all employees have payroll features. Instead of one large interface, split it into IWork
, IManage
, IPayroll
so classes only implement what they need.
5. Dependency Inversion Principle (DIP)
Definition: High-level modules should not depend on low-level modules; both should depend on abstractions.
Example:
👉 This tightly couples UserService
with MySQLDatabase
.
✅ Better approach:
Now, you can inject any database (MySQL, MongoDB, SQL Server) without modifying UserService
.
Real-Time Example:
In a .NET Core Web API, you can use Dependency Injection (DI) to register services like ILogger
, IRepository
, or IDatabase
so that switching implementations doesn’t require changing core business logic.
✅ Benefits of SOLID Principles
-
Improved code readability
-
Easy maintenance & testing
-
Encourages reusability & scalability
-
Reduces bugs caused by code changes
-
Supports clean architecture & design patterns
No comments:
Post a Comment