- 作者:老汪软件技巧
- 发表时间: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# 应用程序更加灵活且易于维护。通过理解何时以及如何应用这些模式,您可以构建可扩展且易于扩展的系统。
在继续您的编程之旅时,考虑结合多种模式来解决更大的架构挑战。