SOLID Principles:
The SOLID principles are a set of design principles in object-oriented programming that improve software modularity and make it easier to maintain and scale. They are:
S: Single Responsibility Principle (SRP)
O: Open/Closed Principle (OCP)
L: Liskov Substitution Principle (LSP)
I: Interface Segregation Principle (ISP)
D: Dependency Inversion Principle (DIP)
Below is a thorough Java-based real-time example using a Payment Processing System, demonstrating each SOLID principle with code and explanation.
1. Single Responsibility Principle (SRP)
A class should have only one reason to change
Good Design:
// Handles user-related operations
class UserService {
public void registerUser(String username, String password) {
// logic to register user
}
}
// Handles email sending
class EmailService {
public void sendEmail(String to, String subject, String body) {
// logic to send email
}
}
❌ Bad Design:
class UserService {
public void registerUser(String username, String password) {
// logic to register user
}
public void sendEmail(String to, String subject, String body) {
// logic to send email (should not be here!)
}
}
2. Open/Closed Principle (OCP)
Software entities should be open for extension but closed for modification.
Good Design:
interface PaymentMethod {
void pay(double amount);
}
class CreditCardPayment implements PaymentMethod {
public void pay(double amount) {
System.out.println("Paid " + amount + " using Credit Card.");
}
}
class PayPalPayment implements PaymentMethod {
public void pay(double amount) {
System.out.println("Paid " + amount + " using PayPal.");
}
}
class PaymentProcessor {
public void makePayment(PaymentMethod method, double amount) {
method.pay(amount);
}
}
Usage:
PaymentProcessor processor = new PaymentProcessor();
processor.makePayment(new CreditCardPayment(), 100.0);
processor.makePayment(new PayPalPayment(), 250.0);
3. Liskov Substitution Principle (LSP)
Subtypes must be substitutable for their base types.
Good Design:
abstract class NotificationService {
abstract void sendNotification(String message);
}
class EmailNotification extends NotificationService {
public void sendNotification(String message) {
System.out.println("Email: " + message);
}
}
class SMSNotification extends NotificationService {
public void sendNotification(String message) {
System.out.println("SMS: " + message);
}
}
public class Notifier {
public void notifyUser(NotificationService service, String message) {
service.sendNotification(message);
}
}
Usage:
Notifier notifier = new Notifier();
notifier.notifyUser(new EmailNotification(), "Order Confirmed!");
notifier.notifyUser(new SMSNotification(), "Your OTP is 123456");
4. Interface Segregation Principle (ISP)
Clients should not be forced to depend on interfaces they don't use.
Good Design:
interface Printer {
void print();
}
interface Scanner {
void scan();
}
class MultiFunctionPrinter implements Printer, Scanner {
public void print() {
System.out.println("Printing document...");
}
public void scan() {
System.out.println("Scanning document...");
}
}
class SimplePrinter implements Printer {
public void print() {
System.out.println("Printing document...");
}
}
SimplePrinter is not forced to implement scan().
5. Dependency Inversion Principle (DIP)
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Good Design:
// Abstraction
interface MessageService {
void sendMessage(String message);
}
// Low-level module
class EmailService implements MessageService {
public void sendMessage(String message) {
System.out.println("Sending Email: " + message);
}
}
// High-level module
class NotificationManager {
private MessageService service;
public NotificationManager(MessageService service) {
this.service = service;
}
public void send(String message) {
service.sendMessage(message);
}
}
Usage:
MessageService emailService = new EmailService();
NotificationManager manager = new NotificationManager(emailService);
manager.send("Welcome to the platform!");
No comments:
Post a Comment