您的位置:首页 > 编程语言 > Java开发

设计模式10-责任链模式

2017-08-07 12:18 260 查看
        中国古代对妇女制定了“三从四德”的道德规范,“三从”是指未嫁从父,既嫁从夫,夫死从子。也就是说一位女性在结婚之前要听从父亲,结婚后要听从于丈夫,如果丈夫死了还要听从于儿子。比如要逛街,作为父亲,丈夫或儿子,只有两种选择:要不要承担起责任来,允许她或不允许她逛街;要不就让她请示下一个人。这就延伸出了责任链模式。类图如下:



      上面处理请求有三个实现类,Father,Husband,Son只要实现构造函数和父类中的抽象方法response方法就可以了,具体由谁处理女性提出的请求,都已转移到了Handler抽象类中。
女性接口代码如下:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.
* 女性接口
*/
public interface IWomen {
/**
*获得个人状况,通过返回值确定结婚与否,丈夫是否去世
* @return
*/
public int getType();

/**
*获得个人请示,出去逛街还是吃饭
* @return
*/
public String getRequest();
}


女性实现类代码如下:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.
* 女性类
*/
public class Women implements IWomen{
/**
* 通过参数来描述妇女的个人状况
* 1---未出嫁
* 2---出嫁
* 3---夫死
*/
private int type;
/**
* 妇女的请示
*/
private String request = "";

/**
* 构造函数传递过来请求
* @param type
* @param request
*/
public Women(int type, String request) {
this.type = type;
switch (this.type){
case 1:
this.request = "女儿的请求是:"+request;
break;
case 2:
this.request = "妻子的请求是:"+request;
break;
case 3:
this.request = "母亲的请求是:"+request;
break;
}
}

/**
* 获得妇女的个人状况
* @return
*/
@Override
public int getType() {
return this.type;
}

/**
* 获得妇女的请求
* @return
*/
@Override
public String getRequest() {
return this.request;
}
}


下面我们看看Handler怎么实现,代码如下:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.
* 处理抽象类
*/
public abstract class Handler {
/**
* 定义常量
*/
public final static int FATHER_LEVEL_REQUEST = 1;
public final static int HUSBAND_LEVEL_REQUEST = 2;
public final static int SON_LEVEL_REQUEST = 3;
/**
* 能处理的级别
*/
private int level = 0;
/**
* 责任传递,下一个人责任人是谁
*/
private Handler nextHandler;
public Handler(int level) {
this.level = level;
}

/**
* 一个女性要求逛街或吃饭,你需要处理这个请求
* @param women
*/
public final void HandleMessage(IWomen women){
if (this.level == women.getType()) {
this.response(women);
}else {
//有后续环节才把请求往后传递
if (this.nextHandler != null) {
this.nextHandler.HandleMessage(women);
}else {//已经没有后续处理人了,不用处理了
System.out.println("--没地方请示了,按不同意处理\n--");
}
}

}

/**
* 如果不属于你处理的请求,你应该让她找下一个环节的人,如果女儿出嫁了,
* 还向父亲请示能否逛街,那父亲应该告诉女儿,应该找丈夫请示
* @param handler
*/
public void setNext(Handler handler){
this.nextHandler = handler;
}

/**
* 有请示还需要回应,该方法就是表示回应
* @param women
*/
public abstract void response(IWomen women);

}


   上面使用到了模板方法模式,在模板方法中判断请求的级别和当前能够处理的级别,如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,有下一个环节做出回应,如果已经达到环节结尾,则直接做不同处理。基本方法response需要各个实现类实现,每个实现类只要实现两个职责:一是定义自己能够处理的级别;二是对请求做出回应。

父亲类代码:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.、
* 父亲类
*/
public class Father extends Handler{
/**
* 父亲只处理女儿的请求
*/
public Father() {
super(Handler.FATHER_LEVEL_REQUEST);
}

/**
* 父亲的答复
* @param women
*/
@Override
public void response(IWomen women) {
System.out.println("---------女儿向父亲请示----------");
System.out.println(women.getRequest());
System.out.println("父亲的答复是:同意\n");
}
}


丈夫类:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.
* 丈夫类
*/
public class Husband extends Handler{

/**
* 丈夫只处理妻子的请求
*/
public Husband() {
super(Handler.HUSBAND_LEVEL_REQUEST);
}

/**
* 丈夫请示的答复
* @param women
*/
@Override
public void response(IWomen women) {
System.out.println("---------妻子向丈夫请示----------");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是:同意\n");
}
}


儿子类:
package com.jack.responsibilitychain;

/**
* Created by jack on 2017/8/7.
* 儿子类
*/
public class Son extends Handler{
/**
* 儿子只处理母亲的请求
*/
public Son() {
super(Handler.SON_LEVEL_REQUEST);
}

/**
* 儿子的答复
* @param women
*/
@Override
public void response(IWomen women) {
System.out.println("---------母亲向儿子请示----------");
System.out.println(women.getRequest());
System.out.println("儿子的答复是:同意\n");
}
}


测试代码如下:
package com.jack.responsibilitychain;

import java.util.ArrayList;
import java.util.Random;

/**
* Created by jack on 2017/8/7.
*/
public class MainTest7 {
public static void main(String[] args) throws CloneNotSupportedException {
//随机挑选几个女性
Random random = new Random();
ArrayList<IWomen> womenList = new ArrayList<>();
for (int i=0;i<5;i++){
womenList.add(new Women(random.nextInt(4), "我要出去逛街"));
}
//定义三个请示对象
Father father = new Father();
Husband husband = new Husband();
Son son = new Son();
//设置请示顺序
father.setNext(husband);
husband.setNext(son);
for (IWomen women: womenList) {
father.HandleMessage(women);
}
}

}


测试可能的一种输出如下:
--没地方请示了,按不同意处理
--
--没地方请示了,按不同意处理
--
--没地方请示了,按不同意处理
--
---------女儿向父亲请示----------
女儿的请求是:我要出去逛街
父亲的答复是:同意

---------妻子向丈夫请示----------
妻子的请求是:我要出去逛街
丈夫的答复是:同意

       责任链模式的定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
       责任链模式的重点是在链上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果,其通用类图如下:



优点:
      责任链模式非常明显的优点是将请求和处理分开。请求者可以不用知道谁处理的,处理者可以不用知道请求的全貌,两者解耦,提供系统的灵活性。

缺点:
       责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链同遍历到链尾,特别是在链比较长的时候,性能时一个非常大的问题。二是调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
代码地址:https://github.com/wj903829182/springboot/tree/master/designpattern/src/main/java/com/jack/responsibilitychain
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息