博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从真实项目中抠出来的设计模式——第三篇:责任链模式
阅读量:5330 次
发布时间:2019-06-14

本文共 6628 字,大约阅读时间需要 22 分钟。

一:现实场景

    有时候在开发的过程中,我们经常会根据某个状态的值,写出很多的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             else10             {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             else18             {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             else11             {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);        }    }

 

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

 

转载于:https://www.cnblogs.com/huangxincheng/p/6429284.html

你可能感兴趣的文章
数据持久化时的小bug
查看>>
http://www.bootcss.com/
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
使用命令创建数据库和表
查看>>
【转】redo与undo
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>
String类中的equals方法总结(转载)
查看>>
内存地址对齐
查看>>
创新课程管理系统数据库设计心得
查看>>
管道,数据共享,进程池
查看>>
SDUTOJ3754_黑白棋(纯模拟)
查看>>
把word文档中的所有图片导出
查看>>
ubuntu 18.04取消自动锁屏以及设置键盘快捷锁屏
查看>>
arcgis api 4.x for js 结合 Echarts4 实现散点图效果(附源码下载)
查看>>
YTU 2625: B 构造函数和析构函数
查看>>
apache自带压力测试工具ab的使用及解析
查看>>
加固linux
查看>>