天天看點

組合模式(二)

組合模式(二)

組合模式的使用場景:

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');
           

繼續閱讀