您的位置:首页 > 其它

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

2017-04-08 07:45 441 查看
一:现实场景

    有时候在开发的过程中,我们经常会根据某个状态的值,写出很多的ifelse逻辑,比如拿项目里面的案例来说,如果当前发送的是彩信,此种状态需要如何给实体赋值,如果是短信,邮件又是其他方式的赋值,等等此类,这种情况下一般会写出如下if判断,对吧,真实代码如下:

 if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.邮件))

                {

                    //第三步:动态生成邮件模板

                    var styleInfo = CacheUtil.GetRandomEmailStyle();

                    var tuple = new EdmDraftBoxBLL().GetEdmHtmlTitle(communicationInfo.EDMJson, styleInfo.StyleId);

                    leaflet.Title = tuple.Item1;

                    leaflet.EDMContent = tuple.Item2;

                    leaflet.Header = tuple.Item3;

                    leaflet.SendSMSCount = 1;

                }

                if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.短信))

                {

                    leaflet.SMSContent = communicationInfo.SMSContent;

                    leaflet.SendSMSCount = communicationInfo.SMSCount;

                }

                

                if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信))

                {

                    leaflet.MMSContent = communicationInfo.MMSContent;

                }

上面的代码还是非常简单明了的,程序会根据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

public class MMSComunication : AbstractComunication

    {

        public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)

        {

            if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.彩信))

            {

                leaflet.MMSContent = communicationInfo.MMSContent;

            }

            else

            {

                abstractComunication.HanderRequest(leaflet, communicationInfo);

            }

        }

    }

3.EDMComunication

public class EDMComunication : AbstractComunication

    {

        public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)

        {

            if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.邮件))

            {

                //第三步:动态生成邮件模板

                var styleInfo = CacheUtil.GetRandomEmailStyle();

                var tuple = new EdmDraftBoxBLL().GetEdmHtmlTitle(communicationInfo.EDMJson, styleInfo.StyleId);

                leaflet.Title = tuple.Item1;

                leaflet.EDMContent = tuple.Item2;

                leaflet.Header = tuple.Item3;

                leaflet.SendSMSCount = 1;

            }

            else

            {

                abstractComunication.HanderRequest(leaflet, communicationInfo);

            }

        }

    }

4.SMSComunication

public class SMSComunication : AbstractComunication

    {

        public override void HanderRequest(LeafletEntity leaflet, EventmarketingSmsEdmContentInfo communicationInfo)

        {

            if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.短信))

            {

                leaflet.SMSContent = communicationInfo.SMSContent;

                leaflet.SendSMSCount = communicationInfo.SMSCount;

            }

            else

            {

                abstractComunication.HanderRequest(leaflet, communicationInfo);

            }

        }

    }

5.客户端调用

AbstractComunication communication1 = new EDMComunication();

 AbstractComunication communication2 = new SMSComunication();

AbstractComunication communication3 = new MMSComunication();

 //手工将三个Comunication 凭借成一个链条,形成单链表的模型

 communication1.SetHandler(communication2);

communication2.SetHandler(communication3);

 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);

        }

    }



 

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

相关文章;
从真实项目中抠出来的设计模式——第一篇:策略模式

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

原文地址:http://www.cnblogs.com/huangxincheng/p/6429284.html

.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: