javascript设计模式-组合模式
组合模式所要解决的问题:
可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象。可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象。
客户端代码必须区别对象简单对象和容器对象,而实际上大多数情况下用户认为它们是一样的。对这些类区别使用,使得程序更加复杂。递归使用的时候跟麻烦,而我们如何使用递归组合,
使得用户不必对这些类进行区别呢?
概念:
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
适用场景:
想表示对象的整体-局部结构,
希望用户忽略组合对象与单个对象的不同,用户可以无差别的使用所有对象。
UML图:
javascript中,对于创建动态用户界面来说,组合模式可以算是为其量身定做的,因为HTML结构正好符合组合模式适用场景的结构。
1. 存在一批组织成某种层次体系的对象。
2. 希望对这批对象或者其中某一部分对象实施一个操作。
组合模式擅长对大批量对象进行操作,专为组织这类对象操作从一个层次向下一个层次传递设计,借此可以弱化对象间的耦合关系并且可以互换使用一些类或者实例。使代码模块化程度更高,维护容易。
下面是JS设计模式中的图片库实例:
首先是图片库的构造函数:
function ImagesStore( id ){
this.children = [];
this.element = document.createElement("div");
this.element.id = id;
this.element.className = "imgs-store";
} ImagesStore.prototype = {
constructor : ImagesStore,
add : function( child ){
this.children.push( child );
this.element.appendChild( child.getElement() );
}, remove : function( child ){
for( var node, i=0; node = this.getChild(i); i++ ){
if( node === child ){
this.children.splice( i, 1 );
break;
}
this.element.removeChild( child.getElement() );
}
}, getChild : function( i ){
return this.children[i];
}, show : function(){
this.element.style.display = '';
for( var node, i=0; node = this.getChild(i); i++ ){
node.show();
}
}, hide : function(){
for( var node, i=0; node = this.getChild(i); i++ ){
node.hide();
}
this.element.style.display = 'none';
}, getElement : function(){
return this.element;
}
};
从上面的组合对象中我们可以看出,原型上的 hide 和 show 方法不单单只是对于当前的 element 进行处理,还衍生到其包含的每一个叶对象上执行。这边就体现了组合模式的运行机制,一条命令在多个对象上激发复杂的或者递归的行为。在此处我们可以看到每一个对象中的element属性中都指向了该对象的实质DOM对象,一般来说不会有什么大问题,但是需要注意的是千万小心再将DOM对象中放入引用JS对象的属性,这样会导致在一些浏览器中内存泄露,部分内存无法回收。
下面是子节点image的构造函数:
function ImageItem( src ){
this.element = document.createElement("img");
this.element.src = src;
this.element.className = "img-item";
} ImageItem.prototype = {
constructor : ImagesStore, add : function( child ){
throw new Error("this is image object, no add function");
}, remove : function( child ){
throw new Error("this is image object, no remove function");
}, getChild : function( i ){
throw new Error("this is image object, no getChild function");
}, show : function(){
this.element.style.display = '';
}, hide : function(){
this.element.style.display = 'none';
}, getElement : function(){
return this.element;
}
};
可以明显看出,对于库节点和IMAGE子节点,除了库节点支持add\remove\getChild等结构上的操作之外,其他方法和IMAGE节点并无差别,而对于上层节点,会递归调用下层节点的相应方法,这就是组合模式要做到的。
调用:
var store = new ImagesStore("first");
store.add( new ImageItem("/img/1.jpg") );
store.add( new ImageItem("/img/2.jpg") );
再在对应的DOM中插入store.element 即可以使用 store.show() 等方法进行控制。并且每个对象之间的耦合非常松散,简单的操作处理复杂的结果。
使用组合模式组织起来的对象具有清晰的层次结构,每当对顶层组合对象执行一个操作的时候,实际上是在对整个结构进行深度优先的节点搜索。但是这些优点都是用操作的代价换取的,比如顶级每执行一次 store.show 实际的操作就是整一颗树形结构的节点均遍历执行一次。
组合模式是将一批子对象组织为树形结构,一条顶层的命令会在操作树中所有的对象。提高了代码的模块化程度,对于动态的HTML界面具有很强的适用性。
javascript设计模式-组合模式的更多相关文章
- javascript设计模式——组合模式
前面的话 在程序设计中,有一些和“事物是由相似的子事物构成”类似的思想.组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的“孙对象”构成的.本文将详细介绍组合模式 宏命令 宏 ...
- JavaScript设计模式-组合模式(表单应用实现)
书读百遍其义自见 <JavaScript设计模式>一书组合模式在表单中应用,我问你答答案. 注:小编自己根据书中的栗子码的答案,如有错误,请留言斧正. 另:如有转载请注明出处,谢谢啦 &l ...
- 读书笔记之 - javascript 设计模式 - 组合模式
组合模式是一种专为创建Web上的动态用户界面而量身定制的模式,使用这种模式,可以用一条命令在对各对象上激发复杂的或递归的行为. 在组合对象的层次体系中有俩种类型对象:叶对象和组合对象.这是一个递归定义 ...
- JavaScript高级---组合模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- 16. 星际争霸之php设计模式--组合模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Java设计模式——组合模式
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...
- 【设计模式】Java设计模式 - 组合模式
Java设计模式 - 组合模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- [设计模式] javascript 之 组合模式
组合模式说明 组合模式用于简单化,一致化对单组件和复合组件的使用:其实它就是一棵树: 这棵树有且只有一个根,访问入口,如果它不是一棵空树,那么由一个或几个树枝节点以及子叶节点组成,每个树枝节点还包含自 ...
- javascript设计模式----桥接模式、组合模式、装饰者模式、享元模式
http://blog.csdn.net/painsonline/article/details/7215087 桥接模式:http://www.cnblogs.com/TomXu/archiv ...
随机推荐
- iphone dev 入门实例2:Pass Data Between View Controllers using segue
Assigning View Controller Class In the first tutorial, we simply create a view controller that serve ...
- (C# Debug)A first chance exception of type 'System.ArgumentException' occurred in System.Data.dll
Debug 模式下运行程序的时候,Output 窗口出来个错误“A first chance exception of type 'System.ArgumentException' occurred ...
- Maven本地安装JAR包组件
http://www.mkyong.com/maven/how-to-add-oracle-jdbc-driver-in-your-maven-local-repository/ mvn instal ...
- DG_Oracle DataGuard Failover主备节点切换(案例)
2014-03-09 Created By BaoXinjian Thanks and Regards
- PLSQL_性能优化系列16_Oracle Tuning Analyze优化分析
2014-12-23 Created By BaoXinjian
- 【JavaScript】创建命名空间,Class,LOG
JxUnderscore(function (J, _, root) { var isWindow, deepObject, Namespace, Class, LOG; /** * 一个对象是否为w ...
- 点击Listview弹出PopWindow的用法
先来张截图: 如图点击listview中的Item在item的下方弹出一个框框,这个框框就是用的Popwindow. 用法很简单:首先写一个PopupWindow并自定义它的布局: ...
- setcookie各个参数详解
定义和用法 setcookie() 函数向客户端发送一个 HTTP cookie. cookie 是由服务器发送到浏览器的变量.cookie 通常是服务器嵌入到用户计算机中的小文本文件.每当计算机通过 ...
- log4j 的rootLogger与rootCategory的区别
一句话 rootLogger是新的使用名称,对应Logger类 rootCategory是旧的使用名称,对应原来的Category类 Logger类是Category类的子类,所以,rootCateg ...
- mysql触发器查看
查询触发器列表 SHOW TRIGGERS; 但是这个无法查询到没有权限的触发器,可以试试这个 select * from sym_trigger where source_table_name li ...