文章目录

职责链模式👍

1、定义与核心思想

(1)定义
  • 职责链模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是将多个处理对象连成一条链,请求沿着链传递,直到被某个对象处理。该模式通过解耦请求发送者与接收者,实现动态灵活的处理流程。
(2)核心价值
  • 降低耦合性:发送者无需知道具体处理者。
  • 灵活扩展:可动态调整处理链的顺序或新增节点。
  • 责任分离:每个处理者专注单一职责,符合单一职责原则。

2、模式结构与角色

(1)抽象处理者(Handler)
  • 定义处理请求的接口,维护后继节点的引用
  • 作用:统一处理逻辑,定义链式结构
public abstract class Handler 
{
    protected Handler successor;
    public void SetSuccessor(Handler successor) 
    {
        this.successor = successor;
    }
    public abstract void HandleRequest(int request);
}
(2)具体处理者(ConcreteHandler)
  • 实现具体的处理逻辑,若无法处理则转发请求
  • 关键点:通过条件判断决定是否处理请求
public class ConcreteHandlerA : Handler 
{
    public override void HandleRequest(int request) 
    {
        if (request <= 1000) 
        {
            Console.WriteLine("HandlerA处理请求:" + request);
        } 
        else if (successor != null) 
        {
            successor.HandleRequest(request); // 传递给下个节点
        }
    }
}

public class ConcreteHandlerB : Handler 
{
    public override void HandleRequest(int request) 
    {
        if (request > 1000 && request <= 5000) 
        {
            Console.WriteLine("HandlerB处理请求:" + request);
        } 
        else 
        {
            successor?.HandleRequest(request);
        }
    }
}
(3)客户端(Client)
  • 构建处理链并触发请求:
public class Client 
{
    public static void Main() 
    {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        Handler handlerC = new ConcreteHandlerC();
        
        handlerA.SetSuccessor(handlerB);
        handlerB.SetSuccessor(handlerC);
        
        // 触发请求
        int[] requests = { 500, 2500, 8000 };
        foreach (var request in requests) 
        {
            handlerA.HandleRequest(request);
        }
    }
}
  • 输出示例:
HandlerA处理请求:500
HandlerB处理请求:2500
HandlerC处理请求:8000
  • 作用:通过链式调用实现请求的动态分发。

3、应用场景与案例

(1)多级审批系统
  • 场景:采购审批流程(部门经理→财务总监→CEO)
  • 优势:灵活应对审批规则变化,如新增“董事会审批”节点
public class PurchaseRequest 
{
    public decimal Amount { get; set; }
}

public abstract class Approver 
{
    protected Approver NextApprover;
    public void SetNextApprover(Approver next) => NextApprover = next;
    public abstract void ProcessRequest(PurchaseRequest request);
}

public class Manager : Approver 
{
    public override void ProcessRequest(PurchaseRequest request) 
    {
        if (request.Amount <= 10000) 
        {
            Console.WriteLine("部门经理审批通过");
        } 
        else 
        {
            NextApprover?.ProcessRequest(request);
        }
    }
}

public class CFO : Approver 
{
    public override void ProcessRequest(PurchaseRequest request) 
    {
        if (request.Amount <= 50000) 
        {
            Console.WriteLine("财务总监审批通过");
        } 
        else 
        {
            NextApprover?.ProcessRequest(request);
        }
    }
}
(2)敏感词过滤系统
  • 场景:依次检查涉黄、广告、政治敏感词
  • 扩展性:可动态添加新的过滤规则
public class ContentFilter 
{
    public string Text { get; set; }
}

public abstract class FilterHandler 
{
    protected FilterHandler NextFilter;
    public void SetNextFilter(FilterHandler next) => NextFilter = next;
    public abstract bool Filter(ContentFilter content);
}

public class SexyWordFilter : FilterHandler 
{
    public override bool Filter(ContentFilter content) 
    {
        if (content.Text.Contains("敏感词1")) 
        {
            Console.WriteLine("存在涉黄内容");
            return false;
        }
        return NextFilter?.Filter(content) ?? true;
    }
}

public class AdsFilter : FilterHandler 
{
    public override bool Filter(ContentFilter content) 
    {
        if (content.Text.Contains("广告链接")) 
        {
            Console.WriteLine("存在广告内容");
            return false;
        }
        return NextFilter?.Filter(content) ?? true;
    }
}

4、扩展与优化

(1)动态构建链
  • 通过配置文件或依赖注入动态组装链
  • 优势:无需修改代码即可调整处理顺序
var chain = Configuration.GetSection("Handlers").Get<List<string>>();
Handler root = null;
Handler current = null;
foreach (var handlerName in chain) 
{
    var handler = Activator.CreateInstance(Type.GetType(handlerName)) as Handler;
    if (root == null) root = handler;
    else current.SetSuccessor(handler);
    current = handler;
}
(2)中断链传递
  • 若某个处理者完成请求,可终止传递
  • 应用场景:快速失败(Fast-Fail)机制
public override void HandleRequest(int request) 
{
    if (CanHandle(request)) 
    {
        // 处理逻辑
        return; // 中断传递
    }
    successor?.HandleRequest(request);
}
(3)责任链与中间件
  • ASP.NET Core中间件管道是责任链模式的典型应用
  • 对比:中间件模式强调“请求-响应”双向处理
public class LoggingMiddleware 
{
    private readonly RequestDelegate _next;
    public LoggingMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context) 
    {
        Console.WriteLine("请求开始");
        await _next(context);
        Console.WriteLine("请求结束");
    }
}

4、优缺点分析

(1)优点
  • 解耦请求与处理:发送者无需关注处理细节。
  • 动态配置链结构:支持运行时增减节点。
  • 增强代码复用性:每个处理者独立封装逻辑。
(2)缺点
  • 链过长导致性能问题:请求可能遍历整个链。
  • 请求可能未被处理:需设计兜底逻辑。
  • 调试困难:逻辑分散在多个处理者中。

模板方法模式👍

1、定义与核心思想

(1)定义
  • 模板方法模式(Template Method Pattern)是一种行为型设计模式,其核心思想是定义一个操作中的算法骨架,将某些步骤的具体实现延迟到子类中,使得子类在不改变算法结构的前提下,可以重写算法的某些特定步骤。
  • 该模式通过继承实现代码复用,适用于算法步骤稳定但部分细节可变的场景。
(2)核心原则
  • 算法框架稳定:父类定义算法的整体流程(如流程步骤的调用顺序)。
  • 可变细节延迟到子类:子类负责实现特定步骤的细节。
(3)模式与角色
  • 抽象类(Abstract Class):定义算法的骨架和基本操作(包含具体方法、抽象方法和模板方法)。
  • 具体子类(Concrete Class):实现父类中定义的抽象方法,提供特定步骤的实现。
(4)应用场景
  • 流程审批系统:如请假流程(提交申请→领导审批→HR通知),不同公司的审批步骤可自定义。
  • 日志记录器:记录日志的通用流程(打开连接→写入日志→关闭连接),支持多种存储方式(文件、数据库、邮件)。
  • 数据解析工具:如处理不同格式文件(PDF、DOC、CSV),固定解析步骤(读取→清洗→转换),具体实现由子类完成。

2、C#代码实现

(1)定义抽象类
// 抽象试卷模板类
public abstract class ExamPaperTemplate
{
    // 模板方法:定义答题流程
    public void AnswerQuestions()
    {
        Question1();
        Console.WriteLine($"答案:{Answer1()}");
        Question2();
        Console.WriteLine($"答案:{Answer2()}");
    }

    // 固定步骤(具体方法)
    private void Question1()
    {
        Console.WriteLine("问题1:1+1=?");
    }

    private void Question2()
    {
        Console.WriteLine("问题2:2+2=?");
    }

    // 抽象步骤(由子类实现)
    public abstract string Answer1();
    public abstract string Answer2();
}
(2)实现具体子类
// 学生A的答卷
public class StudentAPaper : ExamPaperTemplate
{
    public override string Answer1() => "2";
    public override string Answer2() => "4";
}

// 学生B的答卷
public class StudentBPaper : ExamPaperTemplate
{
    public override string Answer1() => "3"; // 错误答案示例
    public override string Answer2() => "4";
}
(3)客户端调用
class Program
{
    static void Main()
    {
        ExamPaperTemplate studentA = new StudentAPaper();
        studentA.AnswerQuestions();

        ExamPaperTemplate studentB = new StudentBPaper();
        studentB.AnswerQuestions();
    }
}
  • 输出结果:
问题1:1+1=?
答案:2
问题2:2+2=?
答案:4

问题1:1+1=?
答案:3
问题2:2+2=?
答案:4
(4)关键代码解析
  • 模板方法:AnswerQuestions() 方法定义了答题流程的固定步骤(问题展示和答案输出)。
  • 抽象方法:Answer1()Answer2() 由子类实现,提供可变逻辑。
  • 具体方法:Question1()Question2() 是父类中已实现的固定步骤。
(5)实际案例扩展
  • 案例:多平台支付流程
public abstract class PaymentProcessor
{
    public void ProcessPayment()
    {
        ValidateRequest();
        ExecutePayment();
        SendNotification();
    }

    protected abstract void ExecutePayment();

    private void ValidateRequest() => Console.WriteLine("验证支付请求...");
    private void SendNotification() => Console.WriteLine("发送支付成功通知...");
}

public class AliPayProcessor : PaymentProcessor
{
    protected override void ExecutePayment() => Console.WriteLine("调用支付宝API完成支付");
}

public class WeChatPayProcessor : PaymentProcessor
{
    protected override void ExecutePayment() => Console.WriteLine("调用微信支付API完成支付");
}

3、高级技巧

(1)钩子方法
  • 钩子方法是模板方法模式中的可选步骤,子类可选择性覆盖以微调算法流程。例如:
public abstract class ReportGenerator
{
    public void GenerateReport()
    {
        FetchData();
        if (NeedFormatting()) FormatData();
        SaveToFile();
    }

    protected virtual bool NeedFormatting() => true; // 钩子方法
    protected abstract void FetchData();
    protected virtual void FormatData() => Console.WriteLine("默认数据格式化");
    protected abstract void SaveToFile();
}
(2)与策略模式结合
  • 当需要动态切换算法步骤时,可结合策略模式,通过依赖注入实现步骤的灵活替换。

3、优缺点分析

(1)优点
  • 代码复用性高:公共代码集中在父类,减少重复。
  • 扩展性强:新增子类不影响现有代码,符合开闭原则。
  • 流程控制统一:算法骨架由父类定义,避免子类随意修改流程。
(2)缺点
  • 类膨胀问题:每个子类需单独实现抽象方法,可能导致类数量过多。
  • 继承限制:C#不支持多重继承,若子类需复用其他类功能时受限。
(3)对比其他模式
模式 核心区别
工厂方法模式 关注对象创建,而模板方法关注算法流程。
策略模式 通过组合实现算法替换,模板方法通过继承实现步骤扩展。

迭代器模式👍

1、定义与核心思想

(1)定义
  • 迭代器模式(Iterator Pattern)是一种行为型设计模式,其核心目标是为聚合对象(如集合、列表等)提供一种统一的遍历方式,而无需暴露其内部结构。
  • 通过将遍历逻辑抽象为独立的迭代器对象,实现了数据访问与存储的解耦。
(2)结构与角色
  • 抽象迭代器(Iterator):定义遍历元素的接口(如MoveNext()Current)。
  • 具体迭代器(ConcreteIterator):实现抽象迭代器的逻辑,管理遍历状态(如光标位置)。
  • 抽象聚合(Aggregate):定义创建迭代器的接口(如GetEnumerator())。
  • 具体聚合(ConcreteAggregate):实现聚合对象的具体数据结构(如数组、链表)。
(3)应用场景
  • 集合遍历
    • 统一遍历接口:无论集合内部是数组、链表还是树,客户端均可通过foreach统一处理。
    • 延迟执行(Lazy Evaluation):如LINQ查询通过迭代器延迟执行,仅在遍历时计算结果。
  • 复合数据结构遍历
    • 嵌套结构:例如遍历树形结构时,可通过迭代器实现深度优先或广度优先搜索。
  • 数据流处理
    • 分页加载:从数据库或网络流中分批读取数据,避免一次性加载内存溢出。

2、C#代码实现

(1)基于标准接口的实现
  • C#通过IEnumerableIEnumerator接口原生支持迭代器模式:
    • IEnumerable:定义获取迭代器的方法GetEnumerator()
    • IEnumerator:定义遍历逻辑,包含MoveNext()CurrentReset()方法。
  • 此方式需要手动管理状态,适用于需要高度定制化遍历逻辑的场景
public class CustomList : IEnumerable, IEnumerator {
    private int[] _items = { 1, 2, 3 };
    private int _position = -1;

    public IEnumerator GetEnumerator() {
        Reset();
        return this;
    }

    public bool MoveNext() => ++_position < _items.Length;
    public object Current => _items[_position];
    public void Reset() => _position = -1;
}
(2)使用yield关键字简化实现
  • C#通过yield return自动生成状态机,隐藏了迭代器的复杂性
  • 编译器会生成一个嵌套类,管理CurrentMoveNext()和状态机,适用于快速实现迭代逻辑。
public IEnumerable<char> GetAlphabet() {
    for (char c = 'A'; c <= 'Z'; c++) {
        yield return c; // 自动保存当前状态并返回元素
    }
}
  • 这种方式在内存效率和代码简洁性上优于手动实现
public IEnumerator GetEnumerator() {
    for (int i = 0; i < 26; i++) {
        yield return (char)('A' + i); // 动态生成字符序列
    }
}
(3)泛型迭代器
  • 通过IEnumerable<T>IEnumerator<T>支持类型安全遍历
  • 泛型迭代器避免了装箱/拆箱开销,提高了性能
public class GenericList<T> : IEnumerable<T> {
    private T[] _items;
    public IEnumerator<T> GetEnumerator() {
        foreach (T item in _items) {
            yield return item;
        }
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

3、扩展与进阶

(1)与设计模式的结合
  • 组合模式:迭代器可用于遍历树形结构的组合对象。
  • 工厂方法模式:聚合类通过工厂方法创建特定类型的迭代器。
(2)异步迭代器
  • C# 8.0+支持await foreach异步遍历
  • 适用于IO密集型操作(如网络请求)
public async IAsyncEnumerable<int> FetchDataAsync() {
    while (hasMoreData) {
        var data = await FetchNextPageAsync();
        foreach (var item in data) {
            yield return item;
        }
    }
}
(3)自定义迭代策略
  • 通过扩展方法增强迭代功能
  • 此方法可实现链式查询,类似LINQ
public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
    foreach (T item in source) {
        if (predicate(item)) yield return item;
    }
}

3、优缺点分析

(1)优点
  • 解耦遍历与存储:聚合类只需关注数据存储,遍历逻辑由迭代器独立管理。
  • 支持多种遍历方式:同一集合可提供正向、反向或过滤后的迭代器。
  • 开闭原则:新增迭代器无需修改聚合类代码。
(2)缺点
  • 性能开销:yield生成的状态机可能带来轻微性能损耗,高频场景需谨慎。
  • 复杂性增加:手动实现迭代器需维护状态,代码量较大。

中介者模式

1、定义与核心思想

(1)定义
  • 中介者模式(Mediator Pattern)是一种行为型设计模式,通过引入中介者对象来封装多个对象间的交互,从而将原本复杂的网状通信结构转换为星型结构,降低对象间的直接耦合。
(2)结构与角色
  • 抽象中介者(Mediator):定义通信接口,协调各对象交互。
  • 具体中介者(ConcreteMediator):实现接口,持有所有同事对象引用,处理具体逻辑。
  • 抽象同事类(Colleague):定义与中介者通信的接口。
  • 具体同事类(ConcreteColleague):与其他同事通过中介者通信,而非直接引用。
(3)应用场景
  • UI控件交互:如表单字段联动(如登录界面中单选按钮、输入框的联动)。
  • 分布式系统协调:如订单系统中库存、支付、物流模块的协同。
  • 游戏开发:管理玩家、NPC、场景间的通信。

2、C#代码实现

(1)典型实现
  • 中介者(ChatRoom)负责注册用户并转发消息。
  • 同事类(ChatUser)仅依赖中介者,无需直接引用其他用户
// 1. 定义中介者接口
public interface IChatMediator
{
    void RegisterUser(User user);
    void SendMessage(string message, User sender);
}

// 2. 具体中介者:管理用户及消息分发
public class ChatRoom : IChatMediator
{
    private List<User> _users = new List<User>();

    public void RegisterUser(User user)
    {
        _users.Add(user);
        user.Mediator = this;
    }

    public void SendMessage(string message, User sender)
    {
        foreach (var user in _users.Where(u => u != sender))
        {
            user.Receive(message);
        }
    }
}

// 3. 抽象同事类
public abstract class User
{
    public string Name { get; }
    public IChatMediator Mediator { get; set; }

    protected User(string name) => Name = name;

    public abstract void Send(string message);
    public abstract void Receive(string message);
}

// 4. 具体同事类
public class ChatUser : User
{
    public ChatUser(string name) : base(name) { }

    public override void Send(string message)
    {
        Console.WriteLine($"{Name}发送消息:{message}");
        Mediator.SendMessage(message, this);
    }

    public override void Receive(string message)
    {
        Console.WriteLine($"{Name}收到消息:{message}");
    }
}

// 客户端调用
var mediator = new ChatRoom();
var user1 = new ChatUser("Alice");
var user2 = new ChatUser("Bob");
mediator.RegisterUser(user1);
mediator.RegisterUser(user2);
user1.Send("Hello, Bob!");
(2)扩展实现:事件驱动中介者
  • 结合C#的事件机制,实现松耦合交互
  • 优势:进一步解耦中介者与同事类,适用于异步通信场景
// 定义事件参数
public class MessageEventArgs : EventArgs
{
    public string Message { get; }
    public User Sender { get; }

    public MessageEventArgs(string message, User sender)
        => (Message, Sender) = (message, sender);
}

// 中介者通过事件通知
public class EventMediator
{
    public event EventHandler<MessageEventArgs> MessageReceived;

    public void Broadcast(string message, User sender)
        => MessageReceived?.Invoke(this, new MessageEventArgs(message, sender));
}

// 同事类订阅事件
public class EventUser
{
    public EventMediator Mediator { get; }

    public EventUser(EventMediator mediator)
    {
        Mediator = mediator;
        Mediator.MessageReceived += OnMessageReceived;
    }

    private void OnMessageReceived(object sender, MessageEventArgs e)
    {
        if (e.Sender != this)
            Console.WriteLine($"收到消息:{e.Message}");
    }

    public void Send(string message)
        => Mediator.Broadcast(message, this);
}
(3)实战案例:电商订单系统
  • 需求:订单创建需协调库存锁定、支付处理、物流调度。
  • 优势:交互逻辑集中管理,新增模块时只需修改中介者
public interface IOrderMediator
{
    void LockStock();
    void ProcessPayment();
    void ScheduleDelivery();
    void Rollback();
}

public class OrderSystem : IOrderMediator
{
    private InventoryService _inventory;
    private PaymentService _payment;
    private LogisticsService _logistics;

    public void CreateOrder()
    {
        try
        {
            LockStock();
            ProcessPayment();
            ScheduleDelivery();
        }
        catch
        {
            Rollback();
        }
    }

    public void LockStock() => _inventory.Lock();
    public void ProcessPayment() => _payment.Charge();
    public void ScheduleDelivery() => _logistics.Schedule();
    public void Rollback()
    {
        _inventory.Release();
        _payment.Refund();
    }
}
(4)最佳实践
  • 适用条件:对象间存在复杂网状依赖,且交互频繁变化的场景。
  • 设计原则:
    • 单一职责:中介者仅处理交互逻辑,同事类专注自身行为。
    • 开闭原则:通过扩展中介者而非修改现有代码实现新功能。
  • 性能优化:对于高频交互场景,可结合异步消息队列或缓存机制。

3、优缺点分析

(1)优点
  • 降低耦合:对象间依赖关系从多对多变为一对多,符合迪米特法则。
  • 集中控制:交互逻辑统一管理,便于维护和扩展。
  • 职责清晰:同事类仅关注自身业务,交互职责转移至中介者。
(2)缺点
  • 中介者复杂度高:若交互逻辑复杂,中介者可能成为“上帝对象”。
  • 性能损耗:集中转发可能导致额外开销。
(3)对比其他模式
模式 核心差异
观察者模式 处理一对多依赖,观察者被动接收通知;中介者模式处理多对多交互。
门面模式 封装子系统对外接口(单向);中介者协调内部对象(双向)。
代理模式 控制单个对象访问;中介者管理多个对象交互。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐