重构职责链代码 - 思考

如果可以,请先查看《重构多重嵌套的代码 - 思考》,对于您接下来的阅读会有些帮助。

本文链接:http://www.cnblogs.com/zhenghongxin/p/8687587.html

职责链模式

职责链模式(称责任链模式)将请求的处理对象像一条长链一般组合起来,形成一条对象链。请求并不知道具体执行请求的对象是哪一个,这样就实现了请求与处理对象之间的解耦。

简单的来说,如果你的拥有执行该业务的权限,那么你执行。如果没有此权限,那递交给你的上级。如果上级拥有权限处理该事务,那么上级执行。如果上级没有执行权限,那提交给上级的上级,直到最高权限为止。这条链路上,只要其中一个执行了,那么下面就不用再继续执行下去了。

场景

在节约流量的情况下,我们弹窗的优先级为:文字弹窗 > 图片弹窗 > 视频弹窗 ,可以抽象为:如果文字弹窗允许,那么就执行文字弹窗即可。如果文字弹窗不行,找上级图片弹窗,以此类推,我们容易写出来的代码可能是(依旧是各种嵌套执行,可以查看我的上篇博客):

var h5 = {
    init: function() {

        // 弹出优先级 : 文字 - 图片 - 视频
        h5.popupText();
    },

    /*
     * 文字弹窗
     */
    popupText: function() {
        api.getText().done(function(re) {
            if (re.code == 1) {
                // 显示文字弹窗 ...
            }
        }).always(function(re = {}) {
            if (re.code != 1) {
                h5.popupImg(); // 继续图片弹窗
            }
        });

    },

    /*
     * 图片弹窗
     */
    popupImg: function() {
        api.getImg().done(function(re) {
            if (re.code == 1) {
                // 显示图片弹窗 ...
            }
        }).always(function(re = {}) {
            if (re.code != 1) {
                h5.popupVideo(); // 继续视频弹窗
            }
        });
    },

    /*
     * 视频弹窗
     */
    popupVideo: function() {
        // 显示视频弹窗 ...
    }
}

可以看到,在每个方法中,用if嵌套去判断。或者是更为恐怖的一层多重判断全部挤在一起:

var h5 = {
    init: function() {

        // 弹出优先级 : 文字 - 图片 - 视频
        api.getText().done(function(re) {
            if (re.code == 1) {
                // 显示文字弹窗 ...
            }
            return;
        }).always(function(re = {}) {
                api.getImg().done(function(re) {
                        if (re.code == 1) {
                            // 显示图片弹窗 ...
                        }
             return; }).always(
function(re = {}) { if (re.code != 1) { h5.popupVideo(); // 继续视频弹窗 } }); }); }, }

这样子做的问题在于:

多重嵌套,没有很直观的一个业务体现,新人进来很容易改错,最大的问题在于,如果要改变一下弹窗顺序呢?几乎完全得重新改写,重新测试。某些人会说改写没问题,但新手就是很容易犯这样子的改写错误,而且代码量现在很少。

重写:

var h5 = {
    init: function() {

        // 弹窗职能链调用
        var chain = new MiniChain();
        chain.next(h5.popupText).next(h5.popupImg).next(h5.popupVideo).go();
    },

    /*
     * 文字弹窗
     */
    popupText: function() {
        var isShow = false;
        api.getText().done(function(re) {
            if (re.code == 1) {
                // 显示文字弹窗 ...
                isShow = true;
            } else {
                // 其他场景处理 ...
            }
            return re;
        });
        return isShow;
    }
},

    /*
     * 图片弹窗
     */
popupImg: function() {
    var isShow = false;
    api.getImg().done(function(re) {
        if (re.
        switch == 1) {
            isShow = true;
            // 图片弹窗显示
        }
    });
    return isShow;
},

    /*
     * 视频弹窗
     */
popupVideo: function() {
    // 显示视频弹窗 ...
}
}

职能链的按优先级的配置和调度,最大的重点是:如果我们改变弹窗顺序呢?如何改变?

针对这段代码:

chain.next(h5.popupText).next(h5.popupImg).next(h5.popupVideo).go();

做一下改变即可:

chain.next(h5.popupText).next(h5.popupImg).next(h5.popupVideo).go();

 

posted @ 2018-04-01 18:07  hongxinerke  阅读(310)  评论(0编辑  收藏  举报