优化你的实行行列-组合形式

假如把设想形式当作一门言语的话,我以为组合形式就是内里的数组,或许更确切的说,应当算是一棵树。 树的枝干就是其他形式的运用,比方敕令形式,代办形式,单例形式等等。总的来说,组合形式在这里就相当于一个容器,但也并不是仅仅是个容器(不然,我还给他冠名”形式”).

组合形式+敕令形式

上篇的敕令形式人人应当能够相识到,一个敕令和敕令实行者的相关联数为 zero . 所以你对敕令的实行者做什么都不要紧,然则他的接口必需保持一致。 而这个特征映射出一个原理,就是既然我能够do anything, 意味着我能够在实行者上面加上其他的实行者.
are u ok?
恩恩,I’m fine, fuck u.
固然,这时刻这个实行者就不叫做敕令,而应当改口叫做宏。来,和上一篇一样,说球的题目。

//当点击一个球后,让球往上走,再往右走
var setCommand = function(ele, command) {
    ele.onclick = function() {
        command.exe();
    }
}
var locat = (function() { //实行事宜类
    var ball = getEle("#pic"),
        style = ball.style; //缓存style
    var move = function(direct) {
        return function() {
            var dir;
            switch (direct) {
                case "bottom":
                    dir = parseInt(getLocat(ball).top) || 0;
                    style.top = `${dir+10}px`;
                    break;
                case "right":
                    dir = parseInt(getLocat(ball).left) || 0;
                    style.left = `${dir+10}px`;
                    break;
                default:
                    dir = parseInt(getLocat(ball)[direct]) || 0;
                    style[direct] = `${dir-10}px`;
            }
        }
    }
    return {
        moveUp: move("top"),
        moveDown: move("bottom"),
        moveLeft: move("left"),
        moveRight: move("right")
    }
})();
//封装敕令
var moveUR = (function(){
    var exe = function(){
        locat.moveUp();
        locat.moveRight();
    }
    return  {  //封装敕令
        exe
    }
})();
setCommand(getEle("leftUpBtn"), moveUR); //绑定实行效果的递次

能够看出,上面的代码能够完成基本任务。然则,假如某一天你的leader请求,让小球 上->右->下->左 举行一个轮回回到原始的位置,生怕你的回响反映不是很猛烈。就是在moveUR内里再加些东西呗。呵呵,来,你leader又说了。在上->右->下的时刻转个圈然后->左.(Ps: 转个毛线啊~~~~), 示意听到这里,想一想某天你的leader抽风了,又换一个完成体式格局。 我想,你年都过不好~。
所以,为了让你早些回家,早点见爹妈,早点领年终奖,早点买春运火车票~
我置信,敕令形式是你不贰之选.
我们运用敕令形式重构一下.

//上面部份不动,只将下面部份改写
//敕令鸠合
var command = function(){
    var lists = [];
    return {
        add(command){
            lists.push(command);
        },
        exe(){
            for(var i = 0,command;command = lists[i++];){
                command.exe();
            }
        }
    }
}
//封装敕令
var moveUp = (function(){
    var exe = function(){
        locat.moveUp();
    }
    return {
        exe
    }
})();
var moveLeft = (function(){
    var exe = function(){
        locat.moveLeft();
    }
    return{
        exe
    }
})();
var moveGroup1 = command();  //获得一个敕令集
moveGroup1.add(moveUp);  //增加向上的敕令
moveGroup1.add(moveLeft);  //。。。。
setCommand(getEle("leftUpBtn"), moveGroup1); //给向上的button,绑定向上的实行递次

能够看出,运用组合形式+敕令形式能够圆满的打出4个2+两个王的最终炸弹。 你能够随机的增加你想要的效果,然则条件照样必需保证有一致的接口内容。
如今能够看出组合形式的优点了吧。 想一想,这个形式的特性–行列。没错,组合形式会建立一棵树,而这棵树的枝干全部是有你来增加,你能够让他变成百年梧桐,也能够让他变成行道树,而且挪用的体式格局极为简朴,运用一个接口,这棵树会把你的敕令经由过程茎,一个接一个的运送过去。

talk is cheap, show u code

var moveUP = (function(){
    var exe = funciton(){
        conosle.log("moveUP");
    }
    return {
        exe
    }
})();
var moveLeft = (function(){
    var exe = funciton(){
        conosle.log("moveLeft");
    }
    return {
        exe
    }
})();
var moveBottom = (function(){
    var exe = funciton(){
        conosle.log("moveBottom");
    }
    return {
        exe
    }
})();
var moveRight = (function(){
    var exe = funciton(){
        conosle.log("moveRight");
    }
    return {
        exe
    }
})();
//加一点难度,对敕令举行分组
var moveGrop1 = command();
moveGrop1.add(moveUp);   //moveUp
moveGrop1.add(moveLeft);  //moveLeft
var moveGrop2 = command();
moveGrop2.add(moveBottom);  //moveBottom
moveGrop2.add(moveRight);  //moveRight
var moveGrop3 = command();
moveGrop3.add(moveBottom);  //moveBottom
moveGrop3.add(moveBottom);  //moveBottom
var moveGrop = command();
moveGrop.add(moveGrop1); 
moveGrop.add(moveGrop2);
moveGrop.add(moveGrop3);
moveGrop.exe();  //接下来会按上面的递次一个一个的运转。

能够看出,组合形式最大的一个特性就是分组操纵。将同类操纵(同目标操纵)放在一组。 就像做一个gif了,一个帧+一个帧+一个帧… 比方,我能够蹲下来,然后起跳。 我又能够蹲下来,然后站立,走路。 就能够把一个片断,一个片断组合成你最想要的效果(思念高中时刻没有好好学习排列组合 :(] 而且重用性也是杠杠的。
能够看出,上面的add如许写好蠢。。。 为了满足装逼的需求,决议优化一下。

//敕令鸠合
var command = function(){
  var lists = [];
    return {
        add(){
            for(var i = 0,command; command = arguments[i++];){
                lists.push(command);
            }
          console.log(lists);
        },
        exe(){
            for(var i = 0,command;command = lists[i++];){
                command.exe();
            }
        }
    }
}
//增加敕令
var moveGrop1 = command();
moveGrop1.add(moveUp,moveLeft);   //moveUp,moveLeft
var moveGrop2 = command();
moveGrop2.add(moveBottom,moveRight);  //moveBottom,moveRight
var moveGrop3 = command();
moveGrop3.add(moveBottom,moveBottom);  //moveBottom,moveBottom
var moveGrop = command();
moveGrop.add(moveGrop1,moveGrop2,moveGrop3); 
moveGrop.exe();  //接下来会按上面的递次一个一个的运转。

清洁,美丽,美美的.
然则,世上没有圆满的代码,敕令形式来扩大宏敕令,这个是他的剑,也是他的死穴。 如许会形成,你的根节点和子节点(不可扩大的节点)之间条理的不清晰。所以,平常,我们会在子节点上面加上申明,防备不测增加而致使的失足,不然,bug一出,春运票你也别想买了。
举个栗子:

var moveGrop = command();
moveGrop1.add(moveUP);
moveUP.add(moveLeft);

虽然看上去这段代码很蠢,但事实上,我确切踩过===我也很蠢xxx… 所以,这里愿望警惕人人,愿望把这个毛病的发生率降到 0.000000001%.吧。
固然,一个艺术家,每每会给本身留一手。

var moveUp = (function(){
    var exe = funciton(){
        conosle.log("moveUp");
    }
    var add = function(){
        throw "你很蠢,不,你真的很蠢."
    }
    return {
        exe,add
    }
})();

如许,万一哪天,真的蠢了,好歹也晓得本身怎样蠢的。本身晓得本身蠢就能够了,记得代码写完后,把这段给删了(红脸).

组合形式注重tips

组合形式虽然很strong.然则有些观点性题目,我们照样必需分清晰.

  1. 组合形式里,根节点和子节点并不是父子关联。即,他们之间,并不存在继续关联。只是他们接口名一致罢了。

  2. 字节点对象必需是同类的,这里说说的同类是指完成同一个目标相互协作的。假如将别的一个组的子节点插进来,形成的效果就是over.

  3. 只管给根节点和子节点取望文生义的名字,背面最好标注他们的属性(根,子).

组合形式的其他用途

这个用途出自于< AlloyTeam的曾探\>.(一枚我超等崇敬的大神)
组合形式的特性是子对象职位同等,迥殊相符我们所说的文件扫描功用。 即,文件扫描只需要晓得你的文件名,以及所处的位置即可。
这里我们能够把文件比作子节点,文件夹比作父节点.

var folder = function(name){
    return {
        name,  //文件夹名
        files:[],
        add(){
            for(var i = 0,file;file = arguments[i++];){
                file.parent = this;
                this.files.push(file);
            }
        },
        scan(){  //扫描文件
            for(var file of this.files){
                console.log(file.name);  
            }
        },
        remove(){
            if(!this.parent){
                alert("该文件是更目次,不能删除!");
                return;
            }
            for(var files = this.parent.files,len = files.length-1;len>=0;len--){  //倒叙遍历文件夹
                var file = files[len];
                if(file === this){
                    files.splice(len,1);  //删除文件
                    break;
                }
            }
        }
    }
}
var file = function(name){
    return {
        name,
        scan(){
            console.log(`this is ${name}`);
        },
        remove(){
             if(!this.parent){
                alert("该文件是更目次,不能删除!");
                return;
            }
            for(var files = this.parent.files,len = files.length-1;len>=0;len--){  //倒叙遍历文件夹
                var file = files[len];
                if(file === this){

                    files.splice(len,1);  //删除文件
                    break;
                }
            }
        },
        add(){
            throw "你很蠢,不,你真的很蠢!"
        }
    }
}
var jimmyFolder = folder("jimmy");
var avi1 = file("小泽玛利亚.avi");
var avi2 = file("上野真知子.avi");
jimmyFolder.add(avi1,avi2);
jimmyFolder.scan();  //小泽玛利亚.avi , 上野真知子.avi
avi1.remove();
jimmyFolder.scan();  //上野真知子.avis

恩,get(工口).
固然,这只是一个比较简朴的例子,跟着你对根节点的不停操纵,背面碰到的题目,一定会凸显出来,要晓得,如许,组合形式内里的节点保留是异常耗内存的,所以这个形式一定另有许多能够优化的处所.
末了,照样那句话,不要为了形式而形式。 关于形式而言照样愿望先写,后增加。
ending~

    原文作者:villainhr
    原文地址: https://segmentfault.com/a/1190000004321390
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞