博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
责任链与装饰者模式(基本介绍)【设计模式1】
阅读量:6415 次
发布时间:2019-06-23

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

【前言】 本人从事了.net开发近10年,现在从.net转型到Java不足2月,所以所见所想都带着很深的.net烙印,不过也有很大可能是java翻译成.net,之后我又给转回java了。

【责任链模式】

外置方式

传统的责任链模式是一个请求有很多处理类,将这些处理类排列成一个顺序数组,如果某一个处理类能够处理,则中止请求;如果不能,则依次继续请求直到全部请求完毕。

用代码表示,就是如下所示:

1 //上下文环境 2 public class Context { 3     public String getHandlerName() { 4         return handlerName; 5     } 6  7     public void setHandlerName(String handlerName) { 8         this.handlerName = handlerName; 9     }10 11     public String getHandlerResult() {12         return handlerResult;13     }14 15     public void setHandlerResult(String handlerResult) {16         this.handlerResult = handlerResult;17     }18 19     public boolean isHasHandled() {20         return hasHandled;21     }22 23     public void setHasHandled(boolean hasHandled) {24         this.hasHandled = hasHandled;25     }26 27     String handlerName;28 29     String handlerResult;30 31     boolean hasHandled;32 33 }34 //接口35 public interface IOuterHandler {36     boolean canHandler(Context context);37 38     void handler(Context context);39 }
接口以及上下文环境
1 //实现类A 2 public class AOuterHandler implements IOuterHandler { 3  4     private static String HandleName="A"; 5  6     @Override 7     public boolean canHandler(Context context) { 8         return  context.getHandlerName()==HandleName; 9     }10 11     @Override12     public void handler(Context context) {13         context.setHandlerResult("没错,就是我处理的:"+this.getClass().getSimpleName());14         context.setHasHandled(true);15     }16 }17 18 //实现类B19 public class BOuterHandler implements IOuterHandler {20     private static String HandleName="B";21 22     @Override23     public boolean canHandler(Context context) {24         return  context.getHandlerName()==HandleName;25     }26 27     @Override28     public void handler(Context context) {29         context.setHandlerResult("没错,就是我处理的:"+this.getClass().getSimpleName());30         context.setHasHandled(true);31     }32 }33 34 //实现类C35 public class COuterHandler implements IOuterHandler {36     private static String HandleName="C";37 38     @Override39     public boolean canHandler(Context context) {40         return  context.getHandlerName()==HandleName;41     }42 43     @Override44     public void handler(Context context) {45         context.setHandlerResult("没错,就是我处理的:"+this.getClass().getSimpleName());46         context.setHasHandled(true);47     }48 }
几个实现子类

之后我们就需要将这些处理类组装成责任链进行处理,具体代码如下:

1 public class Executor { 2     public static void main(String[] args){ 3         ArrayList
handlers=getHandlers(); 4 Context context1=new Context(); 5 context1.setHandlerName("A"); 6 System.out.println(Exe(handlers,context1).getHandlerResult()); 7 8 Context context2=new Context(); 9 context2.setHandlerName("C");10 System.out.println(Exe(handlers,context2).getHandlerResult());11 }12 13 private static ArrayList
getHandlers() {14 ArrayList
handlers = new ArrayList<>();15 handlers.add(new AOuterHandler());16 handlers.add(new BOuterHandler());17 handlers.add(new COuterHandler());18 return handlers;19 }20 21 private static Context exe(ArrayList
handlers,Context context){22 if(handlers!=null&&handlers.size()!=0){23 handlers.forEach(handler->{24 if(context.isHasHandled()){25 return;26 }27 if(handler.canHandler(context)){28 handler.handler(context);29 }30 });31 }32 return context;33 }34 }

 

我们可以看见,exe方法就是实现的主体(这里用了foreach函数,所以没有进行短路处理,实际上如果context.isHasHandled==true后,没有必要进行后面的循环),原则就是当前类是否能够处理,如果不能,就交付给下一个处理函数,当然可能是到最后也没有被处理,这种情况可以不处理直接返回,也可能是使用默认处理函数,不过这不重要了。这种处理方式是存在缺陷的,就是俩个handler想联合处理,是做不到的。所以责任链模式,就发展出内置的形式。

内置方式

内置方式还是看代码:

//Contenx略,见上文public interface IInnerHandler {    void  setHandler(IInnerHandler handler);    void hanlder(Context context);}
内置接口
1 //类A 2 public class AInnerHandler implements IInnerHandler { 3     private static String HandleName="A"; 4     private  IInnerHandler handler; 5  6     @Override 7     public void setHandler(IInnerHandler handler) { 8         this.handler=handler; 9     }10 11     @Override12     public void hanlder(Context context) {13         if(context.getHandlerName().equals(HandleName)){14             context.setHandlerResult("没错,就是我处理的:"+this.getClass().getSimpleName());15             //不需要这句,因为没有意义了16             //context.setHasHandled(true);17         }else {18             handler.hanlder(context);19         }20     }21 22 //类B23 public class BInnerHandler implements IInnerHandler {24     private static String HandleName="A";25     private static String HandleName2="C";26     private  IInnerHandler handler;27 28     @Override29     public void setHandler(IInnerHandler handler) {30         this.handler=handler;31     }32 33     @Override34     public void hanlder(Context context) {35         if(HandleName.equals(context.getHandlerName())||HandleName2.equals(context.getHandlerName())){36             for (int i=0;i<3;i++){37                 handler.hanlder(context);38             }39         }40     }41 }42 //类C43 44 public class CInnerHandler implements IInnerHandler {45     private static String HandleName="C";46     private  IInnerHandler handler;47 48     @Override49     public void setHandler(IInnerHandler handler) {50         this.handler=handler;51     }52 53     @Override54     public void hanlder(Context context) {55         if(context.getHandlerName().equals(HandleName)){56             String resultInfo="***没错,就是我处理的:"+this.getClass().getSimpleName();57             if(context.getHandlerResult()==null){58                 context.setHandlerResult(resultInfo);59             }else {60                 context.setHandlerResult(context.getHandlerResult() + "\n" + resultInfo);61             }62         }else {63             handler.hanlder(context);64         }65     }66 }
内置实现类

之后我们将内置实现类组合实现责任链处理

 

1 public class Executor { 2     public static void main(String[] args){ 3         IInnerHandler handler=getHandler(); 4  5         Context context1=new Context(); 6         context1.setHandlerName("A"); 7         handler.hanlder(context1); 8         System.out.println(context1.getHandlerResult()); 9 10         Context context2=new Context();11         context2.setHandlerName("C");12         handler.hanlder(context2);13         System.out.println(context2.getHandlerResult());14     }15 16     private static IInnerHandler getHandler() {17         IInnerHandler aHandler=new AInnerHandler(),bHandler=new BInnerHandler(),cHandler=new CInnerHandler();18         bHandler.setHandler(cHandler);19         aHandler.setHandler(bHandler);20         return  aHandler;21     }22 }

处理的结果如下:

 我们可以看见,内置完全不同于外置,对于A、C类来说,他的作用就是处理,如果处理不了让下一个类处理,这和外置是类似的。但是B类,他可以自己处理,也可以和A,C联合处理。本例中,B就自己未做处理,只是让C处理了三次。所以明显可以看出内置功能更加强大。但是等等,像B,C这种组合,明显是装饰者模式,怎么是责任链呢?

【装饰者模式】

什么是装饰者?还是看代码吧

1 //上下文 2 public class Context { 3     private ArrayList
arrayList=new ArrayList
(); 4 public ArrayList
getArrayList(){ 5 return arrayList; 6 } 7 public void add(String moreInfo){ 8 arrayList.add(moreInfo); 9 }10 }11 //装饰者接口12 public interface IDecorator {13 void setDecorator(IDecorator decorator);14 15 void domore(Context context);16 }
接口和上下文
1 //ADecorator 2 public class ADecorator implements IDecorator { 3     IDecorator decorator; 4  5     public void setDecorator(IDecorator decorator) { 6         this.decorator = decorator; 7     } 8  9     public void domore(Context context) {10         context.add(this.getClass().getSimpleName());11         decorator.domore(context);12         context.add(this.getClass().getSimpleName());13     }14 }15 16 // BDecorator17 public class BDecorator implements IDecorator {18     IDecorator decorator;19 20     public void setDecorator(IDecorator decorator) {21         this.decorator = decorator;22     }23 24     public void domore(Context context) {25         context.add(this.getClass().getSimpleName());26         decorator.domore(context);27         context.add(this.getClass().getSimpleName());28     }29 }30 31 //CDecorator32 public class CDecorator implements IDecorator {33     IDecorator decorator;34 35     public void setDecorator(IDecorator decorator) {36         this.decorator = decorator;37     }38 39     public void domore(Context context) {40         context.add(this.getClass().getSimpleName());41         //decorator.domore(context);42         context.add("最后一项需要短路");43         context.add(this.getClass().getSimpleName());44     }45 }
装饰者子类实现

装饰者装配和执行的代码如下:

1 public class Executor { 2     public static void main(String[] args) { 3         IDecorator decorator = getDecorator(); 4         Context context = new Context(); 5         decorator.domore(context); 6         context.getArrayList().forEach(mesage -> System.out.println(mesage)); 7     } 8  9     private static IDecorator getDecorator() {10         IDecorator ade = new ADecorator(),11                 bad = new BDecorator(),12                 cad = new CDecorator();13         bad.setDecorator(cad);14         ade.setDecorator(bad);15         return ade;16     }17 }

执行的结果:

 【对比】

责任链(外置):有一个类负责任,在找到这个负责的类之前,其他的类都是看一样是否和自己有关。而找到这个负责的类后,一般也会短路,不会继续往下执行。所以从责任链重点在于谁负责。

装饰者:在构成的链路中,每一个类都发挥自己的作用,并且不会进行短路,直到最后一个类。

责任链(内置):和装饰者在接口层面,出来名字不同,没有什么不一样的。所以它是用装饰者的身体,装责任链的思想。是一个杂交体。至于是责任链还是装饰者,就看内部实现是否有短路,是否有具体负责任的。很可能是俩个都有。

【思考】

责任链和装饰者这种变形,是否是java中常用的,是否有其他变形的实现呢?答案是有,下节将让你看见不一样的责任链(装饰者)

转载于:https://www.cnblogs.com/SharePointApp/p/10340578.html

你可能感兴趣的文章
网页端压缩解压缩插件JSZIP库的使用
查看>>
php和java的一些比较
查看>>
html5的自定义data-*属性和jquery的data()方法的使用示例
查看>>
GET和POST的区别
查看>>
【Scala】Scala技术栈
查看>>
C语言中二维字符数组的定义和初始化
查看>>
源程序出现各种奇怪的符号P
查看>>
【svn】 linux svn 强制提交注释
查看>>
P6 EPPM R16.1安装与配置指南(一)
查看>>
sys模块 和os模块
查看>>
Redhat修改主机名_Red hat怎么永久修改主机名hostname(转)
查看>>
javascript运算符——条件、逗号、赋值、()和void运算符
查看>>
网络包
查看>>
dll版本冲突的解决方法
查看>>
卡方检验(Chi-square test/Chi-Square Goodness-of-Fit Test)
查看>>
在.jsp中非表单请求action的几种方式总结
查看>>
爬取熊猫TV,javascript,selenium,模拟点击
查看>>
厦门大学2016年高等代数考研试题参考解答
查看>>
[转] C# 获取程序运行目录
查看>>
c++ 基于wincrypt的DES CBC模式加解密
查看>>