C# 高级设计模式:从理论到实践
设计模式 (Design Patterns) 是解决典型软件架构问题的经过验证的方案。在初级层面,开发者会接触到 Singleton、Factory 或 Adapter。然而,要在 .NET 平台上创建灵活、可维护且可扩展的系统,必须掌握更复杂的行为型和结构型模式。本文将深入探讨三种高级模式:Chain of Responsibility、State 和 Visitor。每种模式都将通过 C# 的实际示例进行说明,并利用现代语言特性(records、pattern matching、generics)。
1. Chain of Responsibility (职责链模式)
Chain of Responsibility 模式允许将请求沿处理链顺序传递,直到某个处理器处理该请求。这消除了发送方与接收方之间的硬绑定。在 C# 中,它常用于 ASP.NET Core 的 middleware 或数据验证。
示例:权限检查系统
假设我们有一个执行操作的请求。每个处理器检查一个条件(身份验证、授权、限制)。
// 基类处理器public abstract class Handler{ protected Handler? NextHandler;
public void SetNext(Handler handler) => NextHandler = handler;
public abstract void Handle(RequestContext context);}
public class AuthenticationHandler : Handler{ public override void Handle(RequestContext context) { if (context.IsAuthenticated) { Console.WriteLine("Authentication passed."); NextHandler?.Handle(context); } else { Console.WriteLine("Error: user not authenticated."); } }}
public class AuthorizationHandler : Handler{ public override void Handle(RequestContext context) { if (context.Role == "Admin") { Console.WriteLine("Authorization passed."); NextHandler?.Handle(context); } else { Console.WriteLine("Error: insufficient permissions."); } }}
// 请求上下文public record RequestContext(bool IsAuthenticated, string Role);
// 使用var authHandler = new AuthenticationHandler();var authzHandler = new AuthorizationHandler();authHandler.SetNext(authzHandler);
var context = new RequestContext(true, "Admin");authHandler.Handle(context);// 输出:// Authentication passed.// Authorization passed.这种模式非常适合创建处理管道,其中每个步骤可以中断执行或将控制权传递给下一步。
2. State (状态模式)
State 模式允许对象在内部状态改变时改变其行为。从外部看,对象似乎改变了它的类。在 C# 中,通过接口和组合可以方便地实现。
示例:在线商店的订单管理
订单可以处于以下状态:New、Paid、Shipped、Delivered。每个状态定义了哪些操作是允许的。
// 状态接口public interface IOrderState{ void Pay(Order order); void Ship(Order order); void Deliver(Order order);}
// 具体状态public class NewOrderState : IOrderState{ public void Pay(Order order) { Console.WriteLine("Order paid."); order.State = new PaidOrderState(); }
public void Ship(Order order) => Console.WriteLine("Error: order not paid yet."); public void Deliver(Order order) => Console.WriteLine("Error: order not shipped yet.");}
public class PaidOrderState : IOrde
```