组合模式(二)


组合模式的使用场景:

1、存在一批组织成某种层次体系的对象

2、希望对这批对象或其中的一部分对象实施一个操作。


组合模式的特点:

1、组合模式中只有两种类型对象:组合对象、叶子对象

2、这两种类型都实现同一批接口

3、一般我们会在组合对象中调用其方法并隐式调用"下级对象"的方法(这里我们一般采用递归的形式去做)

/**
     * 组合模式应用的场景和特点:
       场景:
       1、存在一批组织成某种层次体系的对象那个
       2、希望对这批对象或其中的一个部分对象实施一个操作

       应用特点:
       1、组合模式中只有两种类型对象:组合对象、叶子对象
       2、这两种类型都实现同一批接口
       3、一般我们会在组合对象中调用其方法并瘾式调用‘下级对象’的方法(这里我们一般采用递归的形势去做)


		 * 场景模拟:
		 *  -> 公司
		 *  	 -> 北京分公司
		 *	    -> 财务部门
		 *	    -> 张1
		 *	    -> 张2
		 *	    -> 张3
		 *	 -> 销售部门
		 *	    -> 张4
		 *	    -> 张5
		 *	    -> 张6
			 -> 上海分公司
		 *	    -> 财务部门
		 *	    -> 张7
		 *	    -> 张8
		 *	    -> 张9
		 *	 -> 销售部门
		 *	    -> 张10
		 *	    -> 张11
		 *	    -> 张12
		 *
		 *实际的任务具体是落实到人上去实施的 也就是说只有人才具有具体的方法实现
		 *
		 */

     //这两个类型必须实现同一个接口
     //添加方法和取得方法
     var CompositeInterface = new Fan.Interface('CompositeInterface',['addChild','getChild']);
     //努力工作和努力睡觉
     var LeafInterface = new Fan.Interface('LeafInterface',['hardworking','sleeping']);

     //组合对象
     var Composite = function(name){
       this.name = name;
       this.type = 'Composite';     //说明对象的类型,方便判断他是组合对象还是叶子对象
       this.children = [];             //承装子类的数组
     };

     Composite.prototype = {
       constructor : Composite,
       addChild : function(child){
         this.children.push(child);
         return this;
       },
       getChild : function(name){
         //接受叶子对象类型数组
         var elements = [];

         //判断对象是否为Leaf类型的
         var pushLeaf = function(item){
           if(item.type === 'Composite'){
             item.children.each(arguments.callee);
           }else if(item.type === 'Leaf'){
             elements.push(item);
           }
         };

         if(name && this.name !== name){  //根据name传值,指定name下的所有类型leaf对象去执行操作
           this.children.each(function(item){
             //如果传入的name是二级子节点名称
             if(this.name === name && item.type === 'Composite'){
               item.children.each(pushLeaf);
             }
             //如果传递的name是三级节点或者是N级
             if(this.name !== name && item.type === 'Composite'){
               item.children.each(arguments.callee);
             }
             //如果传递的name是叶子节点
             if(this.name === name && item.type === 'Leaf'){
               elements.push(item);
             }
           })
         }else{     //不传name,让整个公司所有类型为Leaf的对象去执行操作
           //org.hardworking();没有传值,就遍历公司所有部门
           this.children.each(pushLeaf);
         }
         return elements;
       },
       hardworking : function(name){
         //得到所有的Leaf类型的对象数组
         var leafObject = this.getChild(name);
         for(var i=0; i<leafObject.length; i++){
           leafObject[i].hardworking();
         }
       },
       sleeping : function(name){
         var leafObject = this.getChild(name);
         for(var i=0; i<leafObject.length; i++){
           leafObject[i].sleeping();
         }
       }
     }

     //叶子对象
     var Leaf = function(name){
       this.name = name;
       this.type = 'Leaf';
     };

     Leaf.prototype = {
       constructor : Leaf,
       //叶子节点方法无法再调用下一级
       addChild : function(child){
         throw new Error('不能被使用');
       },
       getChild : function(name){
         if(this.name == name){
           return this;
         }
         return name;
       },
       hardworking : function(name){
         console.log(this.name + '努力工作...');
       },
       sleeping : function(name){
         console.log(this.name + '努力睡觉...');
       }
     }

     //测试数据
     var p1 = new Leaf('张1');
     var p2 = new Leaf('张2');
     var p3 = new Leaf('张3');
     var p4 = new Leaf('张4');
     var p5 = new Leaf('张5');
     var p6 = new Leaf('张6');

     var p7 = new Leaf('张7');
     var p8 = new Leaf('张8');
     var p9 = new Leaf('张9');
     var p10 = new Leaf('张10');
     var p11 = new Leaf('张11');
     var p12 = new Leaf('张12');

     var dept1 = new Composite('北京开发部门');
     dept1.addChild(p1).addChild(p2).addChild(p3);

     var dept2 = new Composite('北京销售部门');
     dept2.addChild(p4).addChild(p5).addChild(p6);

     var dept3 = new Composite('上海开发部门');
     dept3.addChild(p7).addChild(p8).addChild(p9);

     var dept4 = new Composite('上海销售部门');
     dept4.addChild(p10).addChild(p11).addChild(p12);

     var org1 = new Composite('北京分公司');
     org1.addChild(dept1).addChild(dept2);

     var org2 = new Composite('上海分公司');
     org2.addChild(dept3).addChild(dept4);

     var org = new Composite('深圳总部');
     org.addChild(org1).addChild(org2);

     org.hardworking('张7');


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值