• 作者:老汪软件技巧
  • 发表时间:2024-10-11 17:01
  • 浏览量:

行为模式(Behavioral Patterns)专注于对象如何交互和通信,简化职责并创建更灵活的系统。在本文中,我们将深入探讨 C# 中的三个关键行为模式:职责链、命令和观察者模式,了解它们如何帮助您构建更具可维护性和可扩展性的系统。

为什么使用行为模式(Behavioral Patterns)?

行为模式解决了软件设计中的常见挑战,例如如何委派职责,如何使对象在不紧密耦合的情况下相互通信,以及如何保持系统架构的干净和灵活。这些模式简化了代码维护,减少了冗余,并使系统更容易扩展。

职责链(Chain of Responsibility)模式

职责链模式允许您将请求沿着处理链传递,每个处理者可以处理请求或将其传递给下一个处理者。这种模式帮助您在不修改现有代码的情况下添加新行为,因为每个处理者可以决定是否处理请求或传递给下一个。

使用场景

此模式常用于:

它在 C# 中如何工作

假设您正在构建一个订购系统。首先,您希望对输入数据进行清理。随后,您添加了防止暴力破解的功能和缓存检查。每一步都可以实现为链中的单独处理者。

以下是一个简单的 C# 实现:

// 基础处理器类
abstract class RequestHandler
{
    protected RequestHandler nextHandler;
    public void SetNextHandler(RequestHandler handler)
    {
        nextHandler = handler;
    }
    public virtual void Handle(string request)
    {
        if (nextHandler != null)
        {
            nextHandler.Handle(request);
        }
    }
}
// 具体处理器:验证请求数据
class DataValidationHandler : RequestHandler
{
    public override void Handle(string request)
    {
        if (IsValid(request))
        {
            Console.WriteLine("请求数据验证通过。");
            base.Handle(request); // 传递给下一个处理器
        }
        else
        {
            Console.WriteLine("数据无效。请求被拒绝。");
        }
    }
    private bool IsValid(string request)
    {
        // 简单的验证逻辑
        return !string.IsNullOrEmpty(request);
    }
}
// 具体处理器:防止暴力破解
class BruteForceProtectionHandler : RequestHandler
{
    private Dictionary<string, int> failedAttempts = new Dictionary<string, int>();
    public override void Handle(string request)
    {
        if (IsAllowed(request))
        {
            Console.WriteLine("未检测到暴力破解。");
            base.Handle(request);
        }
        else
        {
            Console.WriteLine("请求因暴力破解检测而被阻止。");
        }
    }
    private bool IsAllowed(string request)
    {
        // 简单的暴力破解防护逻辑
        if (!failedAttempts.ContainsKey(request))
        {
            failedAttempts[request] = 0;
        }
        failedAttempts[request]++;
        return failedAttempts[request] <= 3; // 只允许 3 次尝试
    }
}
// 具体处理器:检查缓存
class CacheHandler : RequestHandler
{
    private Dictionary<string, string> cache = new Dictionary<string, string>();
    public override void Handle(string request)
    {
        if (cache.ContainsKey(request))
        {
            Console.WriteLine("返回缓存的响应。");
        }
        else
        {
            Console.WriteLine("处理请求并缓存响应。");
            cache[request] = "处理后的响应";
            base.Handle(request);
        }
    }
}
class Program
{
    static void Main()
    {
        // 设置职责链
        var validationHandler = new DataValidationHandler();
        var bruteForceHandler = new BruteForceProtectionHandler();
        var cacheHandler = new CacheHandler();
        validationHandler.SetNextHandler(bruteForceHandler);
        bruteForceHandler.SetNextHandler(cacheHandler);
        // 示例请求
        string request = "validRequest";
        // 通过职责链处理请求
        validationHandler.Handle(request);
    }
}

解释

在此示例中,每个请求会通过三个处理器:

DataValidationHandler 确保请求数据有效。BruteForceProtectionHandler 检查暴力破解行为。CacheHandler 返回缓存结果,如果没有缓存,则处理并缓存新请求。

这使得系统灵活且易于扩展——每个处理器只关注一个职责,您可以通过添加新的处理器来引入新行为。

职责链模式的应用实例类图_职责链模式应用场景_

常见陷阱命令(Command)模式

命令模式将请求封装为对象,允许它们被排队、记录或撤销。请求的发送者无需了解接收者的任何信息,也不必关心请求将如何处理。

何时使用它在 C# 中如何工作

以下是一个在事务处理场景中使用命令模式的示例:

// 命令接口
public interface ICommand
{
    void Execute();
}
// 转账操作的具体命令
public class TransferMoneyCommand : ICommand
{
    private string _fromAccount;
    private string _toAccount;
    private decimal _amount;
    public TransferMoneyCommand(string fromAccount, string toAccount, decimal amount)
    {
        _fromAccount = fromAccount;
        _toAccount = toAccount;
        _amount = amount;
    }
    public void Execute()
    {
        // 转账的业务逻辑
        Console.WriteLine($"正在从 {_fromAccount} 转账 {_amount}{_toAccount}。");
        // 添加与数据库或外部系统交互的逻辑
    }
}
// 生成报告的具体命令
public class GenerateReportCommand : ICommand
{
    private string _reportType;
    public GenerateReportCommand(string reportType)
    {
        _reportType = reportType;
    }
    public void Execute()
    {
        // 生成报告的业务逻辑
        Console.WriteLine($"正在生成 {_reportType} 报告。");
        // 添加报告生成的逻辑
    }
}
// 调用者类,用于执行命令
public class CommandInvoker
{
    private List _commands = new List();
    public void AddCommand(ICommand command)
    {
        _commands.Add(command);
    }
    public void ExecuteAll()
    {
        foreach (var command in _commands)
        {
            command.Execute();
        }
        _commands.Clear();
    }
}
class Program
{
    static void Main()
    {
        // 创建命令
        var transferCommand = new TransferMoneyCommand("AccountA", "AccountB", 1000);
        var reportCommand = new GenerateReportCommand("Monthly");
        // 调用者执行命令
        var invoker = new CommandInvoker();
        invoker.AddCommand(transferCommand);
        invoker.AddCommand(reportCommand);
        // 执行所有命令
        invoker.ExecuteAll();
    }
}

解释:最佳实践观察者(Observer)模式

观察者模式定义了对象之间的一对多关系,当一个对象(主体)的状态发生变化时,所有依赖它的对象(观察者)都会收到更新通知。这在需要将一个对象的状态反映到多个对象时非常有用。

何时使用它在 C# 中如何工作

以下是使用观察者模式实现的基本发布-订阅模型:

using System;
using System.Collections.Generic;
// 观察者接口
public interface ISubscriber
{
    void Update(string message);
}
// 具体的订阅者类:接收电子邮件通知
public class EmailSubscriber : ISubscriber
{
    private string _email;
    public EmailSubscriber(string email)
    {
        _email = email;
    }
    public void Update(string message)
    {
        Console.WriteLine($"向 {_email} 发送邮件: {message}");
    }
}
// 主体接口
public interface IEmailAlertSystem
{
    void Subscribe(ISubscriber subscriber);
    void Unsubscribe(ISubscriber subscriber);
    void NotifySubscribers(string message);
}
// 具体的主体类:电子邮件通知系统
public class EmailAlertSystem : IEmailAlertSystem
{
    private List _subscribers = new List();
    public void Subscribe(ISubscriber subscriber)
    {
        _subscribers.Add(subscriber);
        Console.WriteLine("已添加订阅者。");
    }
    public void Unsubscribe(ISubscriber subscriber)
    {
        _subscribers.Remove(subscriber);
        Console.WriteLine("已移除订阅者。");
    }
    public void NotifySubscribers(string message)
    {
        foreach (var subscriber in _subscribers)
        {
            subscriber.Update(message);
        }
    }
}
// 示例用法
class Program
{
    static void Main(string[] args)
    {
        // 创建电子邮件通知系统(发布者)
        var alertSystem = new EmailAlertSystem();
        // 创建订阅者(观察者)
        var subscriber1 = new EmailSubscriber("user1@example.com");
        var subscriber2 = new EmailSubscriber("user2@example.com");
        // 订阅通知系统
        alertSystem.Subscribe(subscriber1);
        alertSystem.Subscribe(subscriber2);
        // 通知订阅者一条重要通知
        alertSystem.NotifySubscribers("重要更新:新产品发布!");
        // 移除一个订阅者
        alertSystem.Unsubscribe(subscriber1);
        // 再次通知订阅者
        alertSystem.NotifySubscribers("提醒:不要错过明天的产品发布活动!");
    }
}

解释:

每个订阅者可以动态添加或移除,当发布者通知它们时,它们都会收到更新。

最佳实践其他值得注意的行为模式结论

行为模式是管理对象之间交互的强大方式,使您的 C# 应用程序更加灵活且易于维护。通过理解何时以及如何应用这些模式,您可以构建可扩展且易于扩展的系统。

在继续您的编程之旅时,考虑结合多种模式来解决更大的架构挑战。