责任链模式的定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
例子:古代女子要 “三从四德”,这里的三从是什么呢,是指“未嫁从父,既嫁从夫,夫死从子”。也就是说,一位女性在结婚前听父亲的,结婚后听丈夫的,丈夫G了听儿子的,没有儿子听小叔子的XXX。
需求很简单:通过程序描述一下古代妇女的“三从制度”。我们来看类图
见代码:
/**
*女性接口仅两个方法,一个是获得当前的个人状况,通过返回值决定是结婚了还*是没结婚、丈夫是否在世等,另一个方法是要请示的内容,要出去逛街还是吃饭
*/
public interface IWomen {
//获得个人状况
public int getType();
//获得个人请示,你要干什么?出去逛街?约会?看电影?
public String getRequest();
}
//妇女的实现类
public class Women implements IWomen {
/*
* 通过一个int类型的参数来描述妇女的个人情况
* 1 - - 未出嫁
* 2 - - 出嫁
* 3 -- 夫死
*/
private int type = 0;
private String request = "";
public Women(int _type, String _request){
this.type = _type;
this.request = _request;
}
public int getType(){
return type;
}
@Override
public String getRequest() {
return null;
}
}
//掌权者的接口
public interface IHandler {
//一个女性要求逛街,你要处理这个请求
public void HandlerMessage(IWomen women);
}
public class Father implements IHandler {
@Override
public void HandlerMessage(IWomen women) {
System.out.println("女儿的请示是:" + women.getRequest());
System.out.println("父亲的答复是:同意");
}
}
public class Husband implements IHandler {
@Override
public void HandlerMessage(IWomen women) {
System.out.println("妻子的请示是:" + women.getRequest());
System.out.println("丈夫的答复是:同意");
}
}
public class Son implements IHandler {
@Override
public void HandlerMessage(IWomen women) {
System.out.println("母亲的请示是:" + women.getRequest());
System.out.println("儿子的答复是:同意");
}
}
public class Client {
public static void main(String[] args) {
Random random = new Random();
ArrayList arrayList = new ArrayList<>();
for(int i = 0; i < 5; ++i){
arrayList.add(new Women(random.nextInt(4), "宝宝中秋要去逛街"));
}
IHandler father = new Father();
IHandler husband = new Husband();
IHandler son = new Son();
for(IWomen women:arrayList){
if(women.getType() == 1){
System.out.println("------------女儿向父亲请示------------");
father.HandlerMessage(women);
}else if(women.getType() == 2){
System.out.println("------------妻子向丈夫请示------------");
husband.HandlerMessage(women);
}else if(women.getType() == 3){
System.out.println("------------母亲向儿子请示------------");
son.HandlerMessage(women);
}else{
//暂时先老实待着
}
}
}
}
/*Output
------------母亲向儿子请示------------
母亲的请示是:宝宝中秋要去逛街
儿子的答复是:同意
------------女儿向父亲请示------------
女儿的请示是:宝宝中秋要去逛街
父亲的答复是:同意
------------妻子向丈夫请示------------
妻子的请示是:宝宝中秋要去逛街
丈夫的答复是:同意
------------女儿向父亲请示------------
女儿的请示是:宝宝中秋要去逛街
父亲的答复是:同意
------------妻子向丈夫请示------------
妻子的请示是:宝宝中秋要去逛街
丈夫的答复是:同意
*/
好的,上面的代码已经简单的实现了”三从制度“,但是它有以下明显的缺点
1、职责限定不清楚
对女儿的请示,应该在父亲类中做出决定,父亲有责任、有义务处理女儿的请示,因此Father类应该是知道女儿的请求由自己来处理,而不是在Client类中组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他类进行处理——不应该是这样的。
2、代码臃肿
if … else ,我们不是经常讽刺这样的代码吗。
3、耦合过重
想象一下,如果IHandler的实现类继续拓展怎么办?修改Client类?我们是要尽量遵守开闭原则的呀!
4、异常情况欠考虑
一个妻子如果在请示了自己的父亲怎么办?
ok,带着这些问题,我们重新设计类图
public interface IWomen {
//获得个人状况
public int getType();
//获得个人请示,你要干什么?出去逛街?约会?看电影?
public String getRequest();
}
public class Women implements IWomen {
/*
* 通过一个int类型的参数来描述妇女的个人情况
* 1 - - 未出嫁
* 2 - - 出嫁
* 3 -- 夫死
*/
private int type = 0;
private String 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;
}
}
public int getType(){
return type;
}
@Override
public String getRequest() {
return request;
}
}
public abstract class IHandler {
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 IHandler nextHandler;
public IHandler(int _level){
this.level = _level;
}
public final void HandlerMessage(IWomen women){
if(women.getType() == this.level){
this.response(women);
}else{
if(this.nextHandler != null){
this.nextHandler.HandlerMessage(women);
}
}
}
protected abstract void response(IWomen women);
public void setNext(IHandler _handler){
this.nextHandler = _handler;
}
}
public class Father extends IHandler{
public Father(){
super(IHandler.FATHER_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("------------女儿向父亲请示------------");
System.out.println("女儿的请示是:" + women.getRequest());
System.out.println("父亲的答复是:同意");
}
}
public class Husband extends IHandler {
public Husband() {
super(IHandler.HUSBAND_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("------------妻子向丈夫请示------------");
System.out.println("妻子的请示是:" + women.getRequest());
System.out.println("丈夫的答复是:同意");
}
}
public class Son extends IHandler {
public Son(){
super(IHandler.SON_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("------------母亲向儿子请示------------");
System.out.println("母亲的请示是:" + women.getRequest());
System.out.println("儿子的答复是:同意");
}
}
public class Client {
public static void main(String[] args) {
Random random = new Random();
ArrayList arrayList = new ArrayList<>();
for(int i = 0; i < 5; ++i){
arrayList.add(new Women(random.nextInt(4), "宝宝中秋要去逛街"));
}
IHandler father = new Father();
IHandler husband = new Husband();
IHandler son = new Son();
father.setNext(husband);
husband.setNext(son);
for(IWomen women:arrayList){
father.HandlerMessage(women);
}
}
}
可能例子不是很好,但是”链“还是体现的很明显。责任链的缺点是当链很长的时候不好调试,并且影响了它的执行效率,所以我们要避免超长链的存在。
中秋节快乐~