🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。
毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。每种设计模式都有相应的原理和最佳实践,它们描述了我们日常开发中不断遇到的问题,以及这些问题的核心解决方法。正是因为这种实用性和通用性,设计模式才能在软件开发中广泛地得以应用。设计模式是构建稳健、可扩展和可维护软件的关键工具,为开发者们提供了解决问题的智慧和指导。
职责链模式是一种行为型设计模式,旨在将请求发送者与接收者解耦。它通过创建一个接收者对象链来处理请求,其中每个接收者都可以决定是否处理请求,如果不能处理,则将请求传递给下一个接收者。通常有两种主要实现方式:
第一种实现方式是每个接收者都直接包含对下一个接收者的引用。这样,在接收者不能处理请求时,可以直接将请求传递给下一个接收者。这种方式相对简单,但可能会导致紧密耦合的接收者链。
第二种实现方式是引入一个中间链条类,通常称为中间件或处理器。每个中间件对象负责决定是否处理请求,并决定是否将请求传递给下一个中间件。这种方式更加灵活,允许动态配置和扩展处理链。本例采用了第二种实现方式。
职责链模式是一种有助于实现松耦合的设计模式,通过创建一个请求处理链,可以轻松地扩展和修改请求的处理方式,从而增强了系统的灵活性和可维护性。
职责链模式(Chain of Responsibility Pattern)中的抽象处理者(Handler)是该模式的核心概念,它扮演了以下关键角色和作用:
handleRequest
)。这个接口规定了所有具体处理者必须实现的方法。抽象处理者在职责链模式中起到了定义标准接口、协调请求传递和解耦发送者和接收者的重要作用。每个具体处理者都实现了这个接口,以便在链中处理请求,从而形成了一种灵活的请求处理机制。这种模式适用于需要动态决定请求的处理方式,并且需要将请求在一系列对象之间传递的场景。
职责链模式(Chain of Responsibility Pattern)中的具体处理者(Concrete Handler)是实际处理请求的对象,它扮演了以下关键角色和作用:
handleRequest
或类似的名称,用于具体的请求处理逻辑。具体处理者在职责链模式中扮演了实际处理请求的角色,它们根据自己的能力和责任来决定是否处理请求,以及如何处理。具体处理
职责链模式(Chain of Responsibility Pattern)中的请求类(Request)用于封装请求的信息和数据,它扮演了以下关键角色和作用:
请求类在职责链模式中用于封装和传递请求的关键信息。它有助于请求的处理者识别请求类型、处理请求,同时也提供了一种松耦合的方式来组织和扩展请求处理逻辑。通过合理设计请求类,可以使职责链模式更具可维护性和可扩展性。
职责链模式(Chain of Responsibility Pattern)中的中间链条类(Chain)通常是一个可选的组件,用于协调和管理具体处理者(Concrete Handler)组成的处理链。虽然中间链条类并不是职责链模式的必需部分,但它可以增强模式的灵活性和可配置性,其主要概念和作用如下:
中间链条类在职责链模式中扮演了协调和管理处理者链的角色,它增强了模式的灵活性和可配置性,使得系统能够更容易地适应不同的请求处理需求。虽然不是必需的,但在需要动态配置和管理处理链时,中间链条类可以提供重要的支持。
命名空间ChainOfResponsibility包含领导Leader类充当处理者基类,它包含4个实现类,经理类Manager、总监类Inspector、总经理类President和董事Directorate类,请假信息LeaveRequest类充当请求类,LeaderChain类充当中间链条类。本案例尝试以员工请假来解释职责链模式在审批环节的应用。
public class LeaveRequest {
public int Days { get; set; }
public string Name { get; set; }
public LeaveRequest(int days, string name) {
Days = days;
Name = name;
}
}
请假请求LeaveRequest类,包含需要请假的天数和员工的姓名。一个公开的构造函数表明调用方必须提供请假天数和员工姓名信息。
public abstract class Leader {
protected string Name { get; set; }
protected Leader(string name) {
this.Name = name;
}
public static LeaderChain Chain { protected get; set; }
public abstract void ProcessRequest(LeaveRequest request);
protected void Delivery(LeaveRequest request) {
Chain.DoChain(request);
}
}
领导者Leader类,充当处理者基类,包含领导的姓名Name并维持对中间链的引用。ProcessRequest为处理请假的抽象方法,为处理请假公开了一个调用接口。Delivery则为在不能处理请求时转派至下一个处理者。
public class Manager : Leader {
public Manager(string name) : base(name) { }
public override void ProcessRequest(LeaveRequest request) {
if (request.Days <= 2) {
Console.WriteLine($"{this.Name} approved {request.Name}'s " +
$"leave request for {request.Days} days!");
return;
}
Delivery(request);
}
}
具体处理者,经理Manager类,如果员工的请假天数小于等于2天,则经理有权限批准该请假请求。
public class Inspector : Leader {
public Inspector(string name) : base(name) { }
public override void ProcessRequest(LeaveRequest request) {
if (request.Days <= 4) {
Console.WriteLine($"{this.Name} approved {request.Name}'s " +
$"leave request for {request.Days} days!");
return;
}
Delivery(request);
}
}
具体处理者,总监Inspector类,如果员工的请假天数小于等于4天,则总监有权限批准该请假请求。
public class President : Leader {
public President(string name) : base(name) { }
public override void ProcessRequest(LeaveRequest request) {
if (request.Days <= 8) {
Console.WriteLine($"{this.Name} approved {request.Name}'s " +
$"leave request for {request.Days} days!");
return;
}
Delivery(request);
}
}
具体处理者,总经理President类,如果员工的请假天数小于等于8天,则总经理有权限批准该请假请求。
public class Directorate : Leader {
public Directorate(string name) : base(name) { }
public override void ProcessRequest(LeaveRequest request) {
if (request.Days > 8) {
Console.WriteLine($"{this.Name} approved {request.Name}'s " +
$"leave request for {request.Days} days!");
return;
}
Delivery(request);
}
}
具体处理者,董事Directorate类,如果员工的请假天数大于8天,则需要董事会批准该请假请求。
public class LeaderChain {
private List<Leader> _leaders = new List<Leader>();
private int _cursor = 0;
public void Attach(Leader leader) {
if (leader == null) throw new ArgumentNullException();
_leaders.Add(leader);
}
public bool Detach(Leader leader) {
if (leader == null) throw new ArgumentNullException();
return _leaders.Remove(leader);
}
public void DoChain(LeaveRequest request) {
if (_cursor <= _leaders.Count - 2) {
_leaders[++_cursor].ProcessRequest(request);
}
_cursor = 0;
}
}
中间链条类LeaderChain,首先内部维持对所有处理者的引用,包含的游标_cursor指示链条所处的位置,Attach和Detach方法分别向链条中增加和删除处理者。而DoChain方法则真正转派请求至下一个处理者。
此处需要注意的是,由于请求信息是由第一个处理者直接调用的,所以初始游标位置为0并且在DoChain方法中使用++_cursor作为处理者列表的索引参数。也就是说当第一次转派请求时,索引的值为1(因为使用了++_cursor),即为链条中的第2个处理者。请各位看官仔细思考此处逻辑。
public class Program {
public static void Main(string[] args) {
var leaders = new List<Leader>{
new Manager("Tom"),
new Inspector("Juice"),
new President("Iori"),
new Directorate("Marin")
};
var chain = new LeaderChain();
foreach (var leader in leaders) {
chain.Attach(leader);
}
Leader.Chain = chain;
var requests = new List<LeaveRequest> {
new LeaveRequest(1, "Zhao"),
new LeaveRequest(3, "Qian"),
new LeaveRequest(5, "Sun"),
new LeaveRequest(7, "Li"),
new LeaveRequest(12, "Zhou")
};
foreach (var request in requests) {
leaders[0].ProcessRequest(request);
}
Console.ReadKey();
}
}
以上为调用方代码的示例,首初始化一个处理者列表并增加至中间链条类,之后模拟“赵、钱、孙、李、周”5位同学的请假请求,他们分别要请1、3、5、7、12天假,最后调用ProcessRequest处理请求。以下是这个案例的输出结果:
Tom approved Zhao's leave request for 1 days!
Juice approved Qian's leave request for 3 days!
Iori approved Sun's leave request for 5 days!
Iori approved Li's leave request for 7 days!
Marin approved Zhou's leave request for 12 days!
职责链模式(Chain of Responsibility Pattern)具有多个优点,使其成为一种有用的设计模式,以下是一些主要的优点:
职责链模式有助于构建松耦合、可扩展和灵活的系统,使得请求的处理变得更加可配置和可定制,同时降低了维护成本,提高了代码的可维护性和可扩展性。这些优点使得职责链模式在处理复杂请求处理逻
虽然职责链模式(Chain of Responsibility Pattern)具有许多优点,但也存在一些缺点,需要考虑和权衡:
职责链模式适用于某些特定的场景,但不适合所有情况。在使用时,需要仔细考虑处理链的配置、性能问题以及代码的可维护性,以确保它能够达到预期的效果。
职责链模式(Chain of Responsibility Pattern)适用于以下一些场景和情况:
职责链模式在需要将请求发送给多个潜在处理者,并且能够动态配置和扩展处理链的情况下非常有用。它有助于实现松耦合的系统,提高了系统的灵活性和可维护性,同时符合单一职责原则。