SOLID принципы в C#: теория и практика
SOLID — это акроним пяти фундаментальных принципов объектно-ориентированного программирования и проектирования, сформулированных Робертом Мартином (дядюшкой Бобом). Эти принципы помогают разработчикам создавать гибкий, поддерживаемый и масштабируемый код. В этой статье мы разберем каждый принцип SOLID на языке C# с конкретными примерами кода.
1. Single Responsibility Principle (SRP) — Принцип единственной ответственности
Теория: Каждый класс должен иметь только одну причину для изменения. Другими словами, класс должен отвечать за одну четко определенную задачу.
Практика на C#: Рассмотрим пример нарушения SRP и его исправление.
Нарушение SRP:
public class OrderService{ public void CreateOrder(Order order) { // Логика создания заказа Console.WriteLine("Заказ создан"); // Логика отправки email SendEmail("order@example.com", "Новый заказ"); // Логика логирования File.WriteAllText("log.txt", "Заказ создан"); }}Класс OrderService отвечает за три разные задачи: создание заказа, отправку email и логирование. Это нарушает SRP.
Исправление с соблюдением SRP:
public class OrderService{ private readonly IEmailService _emailService; private readonly ILogger _logger; public OrderService(IEmailService emailService, ILogger logger) { _emailService = emailService; _logger = logger; } public void CreateOrder(Order order) { // Логика создания заказа Console.WriteLine("Заказ создан"); _emailService.SendEmail("order@example.com", "Новый заказ"); _logger.Log("Заказ создан"); }}
public interface IEmailService{ void SendEmail(string to, string message);}
public class EmailService : IEmailService{ public void SendEmail(string to, string message) { Console.WriteLine($"Email отправлен на {to}"); }}
public interface ILogger{ void Log(string message);}
public class FileLogger : ILogger{ public void Log(string message) { File.WriteAllText("log.txt", message); }}Теперь каждый класс отвечает только за свою задачу: OrderService — за управление заказом, EmailService — за отправку писем, FileLogger — за логирование.
2. Open-Closed Principle (OCP) — Принцип открытости/закрытости
Теория: Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации.
Практика на C#: Используем наследование и интерфейсы для расширения функциональности без изменения существующего кода.
Нарушение OCP:
public class PaymentProcessor{ public void ProcessPayment(string paymentType, decimal amount) { if (paymentType == "CreditCard") { // Обработка кредитной карты } else if (paymentType == "PayPal") { // Обработка PayPal } // Добавление нового типа требует изменения класса }}Исправление с соблюдением OCP:
public interface IPaymentMethod{ void Process(decimal amount);}
public class CreditCardPayment : IPaymentMethod{ public void Process(decimal amount) { Console.WriteLine($"Обработка кредитной карты: {amount}"); }}
public class PayPalPayment : IPaymentMethod{ public void Process(decimal amount) { Console.WriteLine($"Обработка PayPal: {amount}"); }}
public class PaymentProcessor{ public void ProcessPayment(IPaymentMethod paymentMethod, decimal amount) { paymen