- chain of Responsibility
责任链模式:为请求创建了一个处理链。每个处理器(handler)接收到这个请求时,都有两种选择:1. 处理这个请求;2 将这个请求传给下一个处理器。
Handlers are lined up one by one, forming a chain - 代码示例
/*
* chain of reaponility
* 职责链模式
*/
using System;
namespace Pattern02
{
class Program
{
static void Main(string[] args)
{
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
///职责链
h1.SetSuccessor(h2);
h2.SetSuccessor(h3);
//测试
h1.HandleRequest(23);
//批量测试
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
foreach (int request in requests)
{
h1.HandleRequest(request);
}
Console.ReadLine();
}
}
/// <summary>
/// Handler
/// </summary>
abstract class Handler
{
protected Handler successor;
//通过这个方法将职责链中的concreteHandler串连起来。
public void SetSuccessor(Handler successor)
{
this.successor = successor;
}
public abstract void HandleRequest(int request);
}
/// <summary>
/// ConcreteHandler1
/// </summary>
class ConcreteHandler1 : Handler
{
public override void HandleRequest(int request)
{
//职责链关键代码。
if (request >= 0 && request < 10)
{
Console.WriteLine($"{this.GetType().Name} handled request {request}");
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
/// <summary>
/// ConcreteHandler2
/// </summary>
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine($"{this.GetType().Name} handled request {request}");
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
/// <summary>
/// ConcreteHandler3
/// </summary>
class ConcreteHandler3 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 20 && request < 30)
{
Console.WriteLine($"{this.GetType().Name} handled request {request}");
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
}
ps:
-
The pattern suggests that you link these handlers into a chain.
Each linked handler has a field for storing a reference to the
next handler in the chain. -
Each handler should make two decisions
when receiving a request:
◦ Whether it’ll process the request.
◦ Whether it’ll pass the request along the chain. -
扩展
可以使用工厂模式依据配置文件实现对职责链得动态连接。
客户端需要考虑得场景:
◦ The chain may consist of a single link.
◦ Some requests may not reach the end of the chain.
◦ Others may reach the end of the chain unhandled.
- 示例二
优化代码,在具体的handler中设置其下一个handler
/*
* chain of Responsibility Pattern
*
*/
using System;
namespace Pattern03
{
class Program
{
static void Main(string[] args)
{
//使用最低级职责,调用
ConsoleLogger logger = new ConsoleLogger();
logger.LogMessage(AbstrcatLogger.Info, "this is a info message");
logger.LogMessage(AbstrcatLogger.Error, "this is a error message");
logger.LogMessage(AbstrcatLogger.Debug, "this is a debug message");
Console.ReadKey();
}
}
//Handler
abstract class AbstrcatLogger
{
public static int Info = 1;
public static int Debug = 2;
public static int Error = 3;
protected int level;
protected AbstrcatLogger nextLogger;//设置chain of Handler
//
public void LogMessage(int level, string message)
{
if (this.level == level)
{
Write(message);
}
///职责链关键代码
if (nextLogger != null)
{
nextLogger.LogMessage(level, message);
}
}
abstract protected void Write(string message);
}
//concreteHandler
class ConsoleLogger : AbstrcatLogger
{
//初始化其职责等级,并设置其一个handler
public ConsoleLogger()
{
this.level = Info;
this.nextLogger = new FileLogger();
}
protected override void Write(string message)
{
Console.WriteLine($"ConsoleLogger:[{level}]: {message}");
}
}
//concreteHandler
class ErrorLogger : AbstrcatLogger
{
public ErrorLogger()
{
this.level = Error;
this.nextLogger = null;
}
protected override void Write(string message)
{
Console.WriteLine($"ErrorLogger:[{level}]: {message}");
}
}
///concreteHandler
class FileLogger : AbstrcatLogger
{
public FileLogger()
{
this.level = Debug;
this.nextLogger = new ErrorLogger();
}
protected override void Write(string message)
{
Console.WriteLine($"FileLogger:[{level}]:{message}");
}
}
}