“戏”说设计模式——责任链模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wfy2695766757/article/details/85105911

首先请出今天的主人公——“齐天大圣”孙悟空

原创文章,禁止转载https://blog.csdn.net/wfy2695766757

 

小时候每到假期,电视上就会播出大家耳熟能详的“西游记” 。

那么今天我们就通过“齐天大圣”孙悟空大闹天宫来描述23种设计模式中之一的“责任链模式

首先我们先了解一下大闹天宫的故事大概:西游记中,孙悟空去东海龙宫抢了金箍棒,又去地府强销生死簿。龙王、阎君去天庭告状,玉帝把孙悟空召入天庭,授他做弼马温。悟空嫌官小,打回花果山,自称“齐天大圣”。玉帝派托塔天王李靖率天兵天将捉拿孙悟空,没有成功,便让孙悟空管理蟠桃园。孙悟空偷吃蟠桃,毁了王母的蟠桃宴,又偷吃了太上老君的金丹后逃离天宫。玉帝再派李天王率天兵捉拿;观音菩萨举荐二郎真君助战;太上老君在旁使暗器帮助,最后悟空被擒。悟空被刀砍斧剁、火烧雷击,甚至置丹炉锻炼四十九日,依然无事,还在天宫大打出手。玉帝降旨请来如来佛祖,才把孙悟空压在五行山下。

在这个故事中有四个关键人物分别为:孙悟空托塔天王李靖玉帝如来佛祖

他们的关系图为:

 

根据剧情发展,我们得到一个规律:孙悟空打败了托塔天王李靖,打败了玉帝,缺败在了如来佛祖的手中。从中得知如来佛祖是最厉害的,没有人能打败他。

根据以上人物关系,我们来通过java描述他们的基本信息:

public class LiJIng {//“托塔天王”李靖

    private String name;

    public LiJIng(String name) {
        this.name = name;
    }

    public boolean fighting(String SunWuKong){
        if ( ! SunWuKong.equals("孙悟空")){//判断是否是与孙悟空打斗
            System.out.println( name + "打败挑战者,挑战者被李靖治罪!");
            //若不是孙悟空,则李靖打败挑战者
            return true;
        }else{
            System.out.println("孙悟空打败" + name + "继续前进,冲向天宫");
            //若是孙悟空,孙悟空打败李靖,继续前进
            return false;
        }
    }
}
public class YuHuangDaDi {//玉皇大帝

    private String name;

    public YuHuangDaDi(String name) {
        this.name = name;
    }

    public boolean fighting(String SunWuKong){
        if ( ! SunWuKong.equals("孙悟空")){
            System.out.println( name + "打败挑战者,挑战者被玉帝治罪!");
            //若不是孙悟空,则玉帝打败挑战者
            return true;
        }else{
            System.out.println("孙悟空打败" + name + "占领天宫,获得“齐天大圣”称号");
            //若是孙悟空,孙悟空打败玉帝,占领天宫
            return false;
        }
    }
}
public class RuLaiFoZu {//如来佛祖

    private String name;

    public RuLaiFoZu(String name) {
        this.name = name;
    }

    public boolean fighting(String SunWuKong) {
        if (!SunWuKong.equals("孙悟空")) {
            System.out.println( name + "打败挑战者,挑战者被如来佛祖治罪!");
            //若不是孙悟空,则如来佛祖打败挑战者
            return true;
        }else{
            System.out.println("孙悟空被" + name + "打败,孙悟空被压在五指山下,大闹天宫结束!");
            //若是孙悟空,孙悟空被佛祖压在五指山下
            return false;
        }
    }
}

接下来,我们设置一个场景“天宫”,所有人都在这个场景里展开故事情节

/**
 * @Author by 飞宇
 * @Date 2018/12/19  20:16
 */
public class TianGong {//天宫作为场景
    public static void main(String[] args) {
        String SunWuKong = "孙悟空";//孙悟空出场
        LiJIng liJIng = new LiJIng("李靖");
        if ( ! liJIng.fighting(SunWuKong)){
            YuHuangDaDi yuHuangDaDi = new YuHuangDaDi("玉帝");
            if ( ! yuHuangDaDi.fighting(SunWuKong)){
                RuLaiFoZu ruLaiFoZu = new RuLaiFoZu("如来佛祖");
                ruLaiFoZu.fighting(SunWuKong);
            }
        }
    }
}

我们看看故事的发展情况:

功夫不负有心人,跑了三个地方和三个人打斗,孙悟空终于完成了大闹天宫的故事。

然而,我们的故事情节是不是有点过于复杂了,找这个打找那个打,打来打去好像孙悟空有点不耐烦了。

他说:“俺老孙打半天打累了,你们为什么这么麻烦,就不能一次都打完了嘛!?”

于是我们根据责任链模式来改进故事的发展情节:

进一步分析,挑战的神仙肯定是不同的,并且每个神仙的战斗力会有区别,所以我们得把这些神仙的打斗情节分开来写,对每个神仙的打斗情节我们进行定义,让打斗的神仙只知道自己是否能打过孙悟空(责任),如果打不过就让更厉害的神仙去打(链条),开始重新定义情节,先抽象出一个神仙的类。

这回我的孙大圣分为三个等级分别为:初级孙悟空,中级孙悟空,高级孙悟空。初级只能打败李靖,中级可以打败李靖和玉帝,高级被如来佛祖打败。

public abstract class ShenXian {//神仙的抽象类
    protected String name;// 抽象出神仙的姓名
    protected ShenXian bigShenXian;//更强大的神仙

    public ShenXian(String name) {
        this.name = name;
    }

    protected ShenXian setBigShenXian(ShenXian bigShenXian){
        this.bigShenXian = bigShenXian;
        return this.bigShenXian; //返回更强大的神仙,链式责任制度
    }

    public abstract void fighting(String SunWuKong);//抽象剧情发展由打斗场景实现。
}

在第3行,神仙认识比自己更厉害的神仙,所以他可以请更厉害的神仙 ,持有强大神仙的引用。

在第9行,将强大神仙注入进来。

在第14行,是我们的情节推动,孙悟空将在这个场景中打斗。

public class LiJIng extends ShenXian{

    public LiJIng(String name) {
        super(name);
    }//“托塔天王”李靖
    @Override
    public void fighting(String SunWuKong){
        if (  SunWuKong.equals("初级孙悟空")){//判断是否是与孙悟空打斗
            System.out.println( name + "打败初级孙悟空,初级孙悟空被李靖治罪!");
            //若不是孙悟空,则李靖打败挑战者
        }else{
            System.out.println("孙悟空打败" + name + "继续前进,冲向天宫");
            //若是孙悟空,孙悟空打败李靖,继续前进
            this.bigShenXian.fighting(SunWuKong);
        }
    }
}

在第14行,表明自己打不过孙悟空,请强大神仙代替自己打斗。 

public class YuHuangDaDi extends ShenXian{

    public YuHuangDaDi(String name) {
        super(name);
    }//玉皇大帝
    @Override
    public void fighting(String SunWuKong){
        if (SunWuKong.equals("中级孙悟空")){
            System.out.println( name + "打败挑战者,挑战者被玉帝治罪!");
            //若不是孙悟空,则玉帝打败挑战者
        }else{
            System.out.println("孙悟空打败" + name + "占领天宫,获得“齐天大圣”称号");
            //若是孙悟空,孙悟空打败玉帝,占领天宫
            this.bigShenXian.fighting(SunWuKong);
        }
    }
}
public class RuLaiFoZu extends ShenXian{

    public RuLaiFoZu(String name) {
        super(name);
    }//如来佛祖
    @Override
    public void fighting(String SunWuKong) {
        if (SunWuKong.equals("高级孙悟空")) {
            System.out.println( name + "打败挑战者,挑战者被如来佛祖治罪!");
            //若不是孙悟空,则如来佛祖打败挑战者
        }else{
            System.out.println("孙悟空被" + name + "打败,孙悟空被压在五指山下,大闹天宫结束!");
            //若是孙悟空,孙悟空被佛祖压在五指山下
            this.bigShenXian.fighting(SunWuKong);
        }
    }
}
/**
 * @Author by 飞宇
 * @Date 2018/12/19  20:16
 */
public class TianGong {//天宫作为场景
    public static void main(String[] args) {

        ShenXian shenXian = new LiJIng("李靖");
        shenXian.setBigShenXian(new YuHuangDaDi("玉帝"))
                .setBigShenXian(new RuLaiFoZu("如来佛祖"));
        shenXian.fighting("初级孙悟空");
        /**
         * 李靖打败初级孙悟空,初级孙悟空被李靖治罪!
         */
        shenXian.fighting("中级孙悟空");
        /**
         * 孙悟空打败李靖继续前进,冲向天宫
         * 玉帝打败挑战者,挑战者被玉帝治罪!v
         */
        shenXian.fighting("高级孙悟空");
        /**
         * 孙悟空打败李靖继续前进,冲向天宫
         * 孙悟空打败玉帝占领天宫,获得“齐天大圣”称号
         * 如来佛祖打败挑战者,挑战者被如来佛祖治罪!
         */
    }
}

在上述代码中对责任链构造对象,(链式)传递(责任)。

这样孙悟空就可以一次性完成打斗,我们看到初级孙悟空只能打过李靖,而高级孙悟空才可以被如来佛祖打败。

目的

孙悟空和重神仙实现了解耦,这样孙悟空只需要给这条责任链传递自己的等级,便可完成自己的情节。不用操心自己是否要找到下一个神仙在开始打斗,只需要交给神仙的接口即可。每个神仙(角色)的责任被划分的非常清楚,然后将这些责任通过(链式)穿起来,形成了完整的责任范围链。如果想让孙悟空打败更多的神仙,只需要按规范添加一个神仙(角色)到责任链中即可,这样一个可伸缩的责任链就完成了,它拥有完美的可扩展性

加个关注吧,下次接着看!谢谢!!!

谢谢https://blog.csdn.net/wfy2695766757

猜你喜欢

转载自blog.csdn.net/wfy2695766757/article/details/85105911
今日推荐