Javascript 设计模式(6) ——组合模式

组合模式就是用小的子对象来构建更大的对象,这些小的子对象也许是由更小的‘‘孙对象’构成的。

在这里插入图片描述
marcoCommand 被称为组合对象,closeDoorCommand、openPcCommand、openQQCommand 都是
叶对象。
在这里插入图片描述
例如 :目前的万能遥控器,包含了关门、开电脑、登录 QQ 这 3 个命令。现在我们需要一个“超级
万能遥控器”,可以控制家里所有的电器,这个遥控器拥有以下功能:
 打开空调
 打开电视和音响
 关门、开电脑、登录 QQ
首先再节点中放置一个按钮button来表示这个超级万能遥控器,遥控器上安装了宏命令,当执行这个宏命令时会依次执行它所有包含的子命令。

<button id="button">按我</button>
//js
//定义宏命令
var MacroCommand = function(){
	return{
		commandsList:[],
		add:function(command){
			this.commandsList.push(command) ;
		},
		execute:function(){
			for(var i = 0,command;command = this.commandList[i++]){
				command.excute();
			}
		}
	}
}
// 定义 叶对象(子命令)
var openAcCommand = {
	execute : function(){
		console.log('打开空调')
	}  
}

家里的电视和音响是连接在一起的,所以可以用一个宏命令来组合打开电视和打开音响的命令

// 定义叶对象(子命令)
var openTvCommand = { 
	 execute: function(){ 
	 	console.log( '打开电视' ); 
 	}	 
 }; 
 var openSoundCommand = { 
 	execute: function(){ 
 		console.log( '打开音响' ); 
 	} 
 }; 
 var macroCommand1 = MacroCommand(); 
 macroCommand1.add( openTvCommand ); 
 macroCommand1.add( openSoundCommand );

关门、打开电脑和打登录 QQ 的命令

//定义叶对象 - 子命令
var closeDoorCommand = { 
	 execute: function(){ 
	 	console.log( '关门' ); 
	 } 
 };
 var openPcCommand = {
 	execute:function(){
 		console.log("开电脑")
 	}
}
var openQQCommand = {
 	execute:function(){
 		console.log("打开QQ")
 	}
}
var macroCommand2 = MacroCommand();
macroCommand2.add(closeDoorCommand );
macroCommand2.add(openPcCommand );
macroCommand2.add(openQQCommand );

把所有的命令组成一个“超级命令”

var macroCommand = MacroCommand();
macroCommand.add(openAcCommand) ;
macroCommand.add(macroCommand1) ;
macroCommand.add( macroCommand2 );

最后给遥控器绑定超级命令

var setCommand = (function( command ){ 
	 document.getElementById( 'button' ).onclick = function(){ 
	 	command.execute(); 
 	} 
 })( macroCommand );

当按下遥控器的按钮时,所有命令都将被依次执行

在这里插入图片描述

从这个例子中可以看到,基本对象可以被组合成更复杂的组合对象,组合对象又可以被组合,
这样不断递归下去,这棵树的结构可以支持任意多的复杂度。

组合模式最大的优点在于可以一致地对待组合对象和基本对象

组合对象可以拥有子节点,叶对象下面就没有子节点, 所以我们也许会发生一些误操作,
比如试图往叶对象中添加子节点。解决方案通常是给叶对象也增加 add 方法,并且在调用这个方
法时,抛出一个异常来及时提醒客户,代码如下:

var MacroCommand = function(){ 
 return { 
	 commandsList: [], 
	 add: function( command ){ 
	 	this.commandsList.push( command ); 
 	 }, 
	 execute: function(){ 
		 for ( var i = 0, command; command = this.commandsList[ i++ ]; ){ 
		 	command.execute(); 
		 } 
	 } 
 } 
}; 
var openTvCommand = { 
	 execute: function(){ 
		 console.log( '打开电视' ); 
	 }, 
	 add: function(){
	 	throw new Error( '叶对象不能添加子节点' ); 
	 } 
};
var macroCommand = MacroCommand(); 
macroCommand.add( openTvCommand ); 
openTvCommand.add( macroCommand ) // Uncaught Error: 叶对象不能添加子节点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值