从真实项目中抠出来的设计模式——第三篇:责任链模式

一:现实场景

有时候在开发的过程中,我们经常会根据某个状态的值,写出很多的ifelse逻辑,比如拿项目里面的案例来说,如果当前发送的是彩信,此种状态需要如何给

实体赋值,如果是短信,邮件又是其他方式的赋值,等等此类,这种情况下一般会写出如下if判断,对吧,真实代码如下:

 1                 if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.邮件))
 2                 {
 3                     //第三步:动态生成邮件模板
 4                     var styleInfo = CacheUtil.GetRandomEmailStyle();
 5
 6                     var tuple = new EdmDraftBoxBLL().GetEdmHtmlTitle(communicationInfo.EDMJson, styleInfo.StyleId);
 7
 8                     leaflet.Title = tuple.Item1;
 9                     leaflet.EDMContent = tuple.Item2;
10                     leaflet.Header = tuple.Item3;
11                     leaflet.SendSMSCount = 1;
12                 }
13
14                 if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.短信))
15                 {
16                     leaflet.SMSContent = communicationInfo.SMSContent;
17                     leaflet.SendSMSCount = communicationInfo.SMSCount;
18                 }
19
20
21                 if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信))
22                 {
23                     leaflet.MMSContent = communicationInfo.MMSContent;
24                 }

上面的代码还是非常简单明了的,程序会根据leaflet.CommunicationtypeEnum的不同做不同的判断,比如说当前状态是邮件的话,程序会从30套邮件

模板库中随机抽取一封,给leaflet的title,header...赋值,有些人可能会说这段代码不难看哈,确实是这样,但是如果面对需求变更呢?比如说后期需要增加微

信,微博渠道,那是不是又要加上两个if才能把这个问题解决呢? 这就违背了设计模式中开闭原则,对吧,面对这种场景,可以用责任链模式摆平。

二:责任链模式

责任链模式讲的就是将请求的发送者和接收者进行分离,避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,

并且沿着这条链传递请求,直到有对象处理它为止,面对需求变更,只需要更加处理类就好了,而且客户端可以按照自己的需求拼接处理链条,是不是很强大。

1. AbstractComunication

    public abstract class AbstractComunication
    {
        AbstractComunication abstractComunication = null;

        public void SetHandler(AbstractComunication abstractComunication)
        {
            this.abstractComunication = abstractComunication;
        }

        public abstract void HanderRequest(LeafletEntity leaflet,
                                          EventmarketingSmsEdmContentInfo communicationInfo);
    }

2. MMSComunication

 1     public class MMSComunication : AbstractComunication
 2     {
 3         public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)
 4         {
 5             if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信))
 6             {
 7                 leaflet.MMSContent = communicationInfo.MMSContent;
 8             }
 9             else
10             {
11                 abstractComunication.HanderRequest(leaflet, communicationInfo);
12             }
13         }
14     }

3.EDMComunication

 1     public class EDMComunication : AbstractComunication
 2     {
 3         public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)
 4         {
 5             if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.邮件))
 6             {
 7                 //第三步:动态生成邮件模板
 8                 var styleInfo = CacheUtil.GetRandomEmailStyle();
 9
10                 var tuple = new EdmDraftBoxBLL().GetEdmHtmlTitle(communicationInfo.EDMJson, styleInfo.StyleId);
11
12                 leaflet.Title = tuple.Item1;
13                 leaflet.EDMContent = tuple.Item2;
14                 leaflet.Header = tuple.Item3;
15                 leaflet.SendSMSCount = 1;
16             }
17             else
18             {
19                 abstractComunication.HanderRequest(leaflet, communicationInfo);
20             }
21         }
22     }

4.SMSComunication

 1     public class SMSComunication : AbstractComunication
 2     {
 3         public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)
 4         {
 5             if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.短信))
 6             {
 7                 leaflet.SMSContent = communicationInfo.SMSContent;
 8                 leaflet.SendSMSCount = communicationInfo.SMSCount;
 9             }
10             else
11             {
12                 abstractComunication.HanderRequest(leaflet, communicationInfo);
13             }
14         }
15     }

5.客户端调用

1                 AbstractComunication communication1 = new EDMComunication();
2                 AbstractComunication communication2 = new SMSComunication();
3                 AbstractComunication communication3 = new MMSComunication();
4
5                 //手工将三个Comunication 凭借成一个链条,形成单链表的模型
6                 communication1.SetHandler(communication2);
7                 communication2.SetHandler(communication3);
8
9                 communication1.HanderRequest(leaflet, communicationInfo);

其实上面的代码,需要绕一下脑子的就是如何通过SetHandler将三个xxxComunication拼接成一个单链表的形式,链表怎么拼接在于客户端如何设置sethandler,

灵活性完全就在客户端这边,然后就非常方便将leaflet在责任链中游走,最终会被某一状态处理逻辑处理,讲到这里,我想大家应该都知道责任链模式是干嘛的了,

由于是真实案例就不方便跑代码了,下面我构建一个责任链模型,大家比照一下就可以了,是不是有种请求和处理的分离,而且我还可以根据需要组合我的责任链,

其实js的冒泡机制就是这种模式的一个体现。

   public abstract class AbstractHandler
    {
        protected AbstractHandler abstractHandler = null;

        public void SetHandler(AbstractHandler abstractHandler)
        {
            this.abstractHandler = abstractHandler;
        }

        public virtual void HandleRequest(int request) { }
    }

   public class ConcreteHandler1 : AbstractHandler
    {
        public override void HandleRequest(int request)
        {
            if (request == 1)
            {
                Console.WriteLine("handler1 给你处理了");
            }
            else
            {
                abstractHandler.HandleRequest(request);
            }
        }
    }

    public class ConcreteHandler2 : AbstractHandler
    {
        public override void HandleRequest(int request)
        {
            if (request == 2)
            {
                Console.WriteLine("handler2 给你处理了");
            }
            else
            {
                abstractHandler.HandleRequest(request);
            }
        }
    }

    public class ConcreteHandler3 : AbstractHandler
    {
        public override void HandleRequest(int request)
        {
            if (request == 3)
            {
                Console.WriteLine("handler3 给你处理了");
            }
            else
            {
                abstractHandler.HandleRequest(request);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            AbstractHandler hander1 = new ConcreteHandler1();
            AbstractHandler hander2 = new ConcreteHandler2();
            AbstractHandler hander3 = new ConcreteHandler3();

            hander1.SetHandler(hander2);
            hander2.SetHandler(hander3);

            hander1.HandleRequest(3);
        }
    }

好了,模板和实际项目的案例都给大家展示了,希望能帮助到你。

时间: 2024-11-05 22:41:37

从真实项目中抠出来的设计模式——第三篇:责任链模式的相关文章

从真实项目中抠出来的设计模式——第二篇:过滤器模式

一:实际场景介绍 我们在给用户做订单催付通知的时候,会有这样的一种场景,用户在系统后台设置一组可以催付的规则,比如说订单金额大于xx元,非黑名单用户,来自 哪个地区,已购买过某个商品,指定某个营销活动的人等等这样的条件,如果这时用户在淘宝上下了一个订单,那程序要判断的就是看一下此订单是否满足这 些规则中的某一个,如果满足,我们给他发送催付通知,这种场景是很多做CRM的同学都会遇到的问题,那针对这种场景,如何更好的规划业务逻辑呢? 二:普通的编程代码 在这里我们就不考虑多筛选条件下的性能,而只从代

Java设计模式(九)责任链模式 命令模式

(十七)责任链模式 责任链模式的目的是通过给予多个对象处理请求的机会,已解除请求发送者与接受者之间的耦合关系.面对对象的开发力求对象之前保持松散耦合,确保对象各自的责任最小化,这样的设计可以使得系统更加容易修改,同时降低产生缺陷的风险. public class ChainTest { public static void main(String[] args) { String pass1="123456"; String pass2="123456"; Stri

PHP设计模式学习笔记: 责任链模式(Chain of Responsibility)

// 抽象书本类 abstract class AbstractBookTopic { abstract function getTopic(); abstract function getTitle(); abstract function setTitle($title_in); } // 书本类,继承自抽象书本类 class BookTopic extends AbstractBookTopic { private $topic; private $title; function __co

设计模式学习笔记之责任链模式

责任链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链检查该请求,并对其进行处理,或者将它传递给下一个对象. 责任链模式有两个角色组成: 抽象处理者角色:它定义了一个处理请求的接口.当然对于链子的不同实现,也可以在这个角色中实现后继链. 具体处理者角色:实现抽象处理者定义的接口,并处理它所负责的请求. 下面是<设计模式>中给出的适用范围:    1) 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定.    2)

设计模式-(15)责任链模式 (swift版)

一,概念: 责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为型模式.在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 主要解决职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了.

大话设计模式读书笔记--19.责任链模式

定义 责任链模式定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 比如: 员工小张向组长申请加薪, 组长没这个权利并将请求告诉部长,部长同意了小张的加薪请求 模式结构 代码实现 场景: 经理可以批准请假, 经理的上级是总监, 总监可以批准加薪 代码实现:点击下载 优点 1.客户端不知道哪一个对象最终处理请求,在不影响客户端的情况下可以动态的重新组织和分配责任 2.链中的对象并不知道链的结构,只需保持

java23种设计模式之十:责任链模式

最近在学习netty中发现其中用到了责任链模式,然后结合自己在写代码中遇到了大量写if...else的情况,决定学习一下责任链模式. 一.什么样的场景下会选择用责任链模式 我们在进行业务逻辑判断时,需要根据传入参数类型的不同做出不同的处理,如果在传入的参数类型相对较少的情况时,可以用if...else来做判断,这样的确是没有什么问题的,但是如果后期由于业务系统的扩展,导致参数类型会随之延伸出很多种不同的处理,这时就需要用责任链模式来抒代码重构,这样会让代码封装的更好.更简洁,阅读性更强,后期如果

重温设计模式(三)——职责链模式(chain of responsibility)

一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所以希望各位多多指教. 二. 什么是链 文章伊始,先让我们了解这个最基本的概念,什么是链. 我给链下了这样的定义: 1. 链是一系列节点的集合. 2. 链的各节点可灵活拆分再重组. 三. 何为职责链 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条

java设计模式(五)责任链模式

很多对象有每个对象对其下家的引用而连接起来形成一条链,请求在这条链上传递,直到链上某个对象决定处理此请求,应用场景如单位审批流程等. 要点:1)抽象处理者角色:定义处理请求接口及设定下家引用    2)具体处理着角色:具体处理请求或选择将请求传给下家 1.抽象处理者角色类,定义处理请求接口及下家引用 public abstract class PriceHandle { protected PriceHandle successor; public void setSuccessor(Price