SOLID 原则在 C# 中的理论与实践
SOLID 是由 Robert Martin(Bob 大叔)提出的面向对象编程与设计的五个基本原则的首字母缩写。这些原则帮助开发者创建灵活、可维护且可扩展的代码。在本文中,我们将通过具体的代码示例,逐一解析 C# 语言中的每个 SOLID 原则。
1. Single Responsibility Principle (SRP) — 单一职责原则
理论:每个类应该只有一个引起变化的原因。换句话说,一个类应该只负责一个明确定义的任务。
C# 实践:让我们看一个违反 SRP 的例子以及如何修正它。
违反 SRP:
public class OrderService{ public void CreateOrder(Order order) { // 创建订单的逻辑 Console.WriteLine("订单已创建"); // 发送邮件的逻辑 SendEmail("order@example.com", "新订单"); // 日志记录的逻辑 File.WriteAllText("log.txt", "订单已创建"); }}OrderService 类负责三个不同的任务:创建订单、发送邮件和日志记录。这违反了 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($"邮件已发送至 {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