Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Triển khai Nguyên tắc Single Responsibility Principle (SRP) trong C#

Single Responsibility Principle (SRP): Một class nên chỉ có một lý do để thay đổi (một trách nhiệm duy nhất).

Vi phạm SRP: Class làm quá nhiều việc

// TRƯỚC: Vi phạm SRP
public class InvitationService
{
    public void SendInvite(string email, string firstName, string lastName)
    {
        // 1. Validate name
        if (string.IsNullOrWhiteSpace(firstName) || string.IsNullOrWhiteSpace(lastName))
            throw new Exception("Name is not valid");

        // 2. Validate email
        if (!email.Contains("@") || !email.Contains("."))
            throw new Exception("Email is not Valid!");

        // 3. Gửi email (phụ thuộc SmtpClient)
        var client = new SmtpClient();
        client.Send(new MailMessage("test@gmail.com", email)
        {
            Subject = "Please Join the Party!"
        });
    }
}

Class này có 3 lý do để thay đổi: quy tắc validate tên, quy tắc validate email, cách gửi email.

Tuân thủ SRP: Tách thành các class nhỏ, mỗi class một trách nhiệm

// SAU: Tuân thủ SRP
// 1. Chỉ lo validate tên
public static class UserNameValidator
{
    public static void Validate(string firstName, string lastName)
    {
        if (string.IsNullOrWhiteSpace(firstName) || string.IsNullOrWhiteSpace(lastName))
            throw new Exception("Name is not valid");
    }
}

// 2. Chỉ lo validate email
public static class EmailValidator
{
    public static void Validate(string email)
    {
        if (!email.Contains("@") || !email.Contains("."))
            throw new Exception("Email is not Valid!");
    }
}

// 3. Chỉ lo gửi email
public class EmailSender
{
    public void Send(string from, string to, string subject, string body)
    {
        using var client = new SmtpClient();
        client.Send(new MailMessage(from, to) { Subject = subject, Body = body });
    }
}

// 4. Orchestrator (coordinator) - chỉ điều phối
public class InvitationService
{
    private readonly EmailSender _sender;
    public InvitationService(EmailSender sender) => _sender = sender;

    public void SendInvite(string email, string firstName, string lastName)
    {
        UserNameValidator.Validate(firstName, lastName);
        EmailValidator.Validate(email);
        _sender.Send("test@gmail.com", email, "Please Join the Party!", "Body...");
    }
}

Lợi ích

  • Dễ hiểu, dễ bảo trì: Mỗi class nhỏ, rõ ràng.
  • Dễ test: Mock từng validator, sender riêng biệt.
  • Tái sử dụng: Validator dùng được ở nơi khác.
  • Giảm coupling: InvitationService không biết chi tiết SMTP.

Dấu hiệu vi phạm SRP

  • Class lớn (> 200 dòng), nhiều phương thức không liên quan.
  • Nhiều using namespace khác nhau (System.Net.Mail, System.Data.SqlClient...).
  • Thay đổi một nghiệp vụ làm hỏng nghiệp vụ khác.
  • Khó đặt tên class (tên chung chung như Manager, Helper, Service, Processor).

Lưu ý: SRP không có nghĩa là class chỉ có 1 method. Nghĩa là tất cả methods cùng phục vụ một trách nhiệm nghiệp vụ duy nhất.