手机版

组合模式在设计模式中的应用

时间:2021-10-30 来源:互联网 编辑:宝哥软件园 浏览:

定义

组合,顾名思义,是指从包含多个部分的对象创建单个实体。这个单一实体将被用作所有这些组件的访问点,这大大简化了操作,但它也可能具有很大的欺骗性,因为没有隐式的方法来清楚地指示该组合包含多少组件。组合模式的目标是将客户端程序的内部架构和复杂元素解耦,这样客户端程序就可以平等地对待所有子元素。

每个子节点都可能很复杂。对于父节点,不需要知道子节点的复杂度,也不需要意识到子节点的复杂度,只需要关注子节点的具体方法,然后子节点就可以使用了。父子关系被简化了。

子节点也是如此。过多的界面暴露有时是一种滥用,也减少了对外界的依赖。

我们最好用例子来说明这种结合。在下图中,您可以看到两种不同类型的对象:容器和库是组合,图像是树叶。组合可以容纳孩子,但通常不会实现更多的行为。叶子包含了大部分的行为,但是不能带孩子,至少在传统的组合例子中不能。

2016518103600142.png  (550341)

本示例创建一个图片库作为复合图案的示例。只有三个层次:相册、图库、图片。相册和图库会合并,图片为树叶,如上图所示。这是一个比组合本身有更明确要求的结构,但是对于这个例子来说,将这些级别限制在组合或叶子上是有意义的。标准组合不限制哪些结构级别可以有刀片,也不限制刀片的数量。

首先,您应该为相册和图库创建一个GalleryComposite“类”。请注意,我正在使用jQuery来执行DOM操作,以简化过程。

var gallery composite=function(heading,id){ this . children=[];this . element=$(' div id=' id ' ' class=' composite-gallery '/div ')。追加(' h2 '标题'/H2 ');} gallery composite . prototype={ add : function(child){ this . children . push(child);this . element . append(child . GetElement());},remove:函数(子){ for (var node,I=0;node=this . GetChild(I);I){ if(node==child){ this . children . splice(I,1);this . element . detach(child . GetElement());返回真;} if (node.remove(child)) {返回true} }返回false},getChild:函数(I){ return this . children[I];},hide:函数(){ for (var node,I=0;node=this . GetChild(I);I){ node . hide();} this . element . hide(0);},show : function(){ for(var node,I=0;node=this . GetChild(I);I){ node . show();} this . element . show(0);},getElement:函数(){返回this.element}}这个位置有点棘手。你能允许我多解释一下吗?同时,我们使用add、remove和getChild getChild方法来构建这个组合。在这个例子中,remove和getChild实际上并没有被使用,但是它们对于创建动态组合非常有用。隐藏、显示和getElement方法用于操作DOM。这种组合旨在作为库的表示在页面上呈现给用户。这种组合可以通过隐藏和显示来控制这些库元素。如果在相册上调用hide,整个相册都会消失,或者可以只在单个图像上调用,这样就只有那个图像会消失。

现在,创建一个GalleryImage类。请注意,它使用的方法与GalleryComposite完全相同。换句话说,它们实现了相同的接口,只不过图像是一片叶子,所以它们实际上并不对子项相关的方法执行任何操作,就好像它们没有任何子项一样。组合必须使用相同的接口运行,因为组合元素不知道它是在添加另一个组合元素还是叶元素,所以如果您试图在其子元素上调用这些方法,您需要完全运行而没有任何错误。

var GalleryImage=function (src,id){ this . children=[];this.element=$('img /')。attr('id ',id)。attr('src ',src);}GalleryImage.prototype={ //由于这是叶子,所以它不使用这些方法,//但是必须实现它们才能算作实现//Composite interface add:函数(){ }、remove:函数(){ }、getChild:函数(){ }、hide:函数(){ this . element . hide(0);},show : function(){ this . element . show(0);},getElement:函数(){返回this.element}}既然已经有了对象的原型,现在就可以使用它了。从下面可以看到实际构建图像库的代码。

var container=new gallery composite(',' all gallery ');var gallery1=新GalleryComposite('Gallery 1 ',' Gallery 1 ');var gallery2=新GalleryComposite('Gallery 2 ',' Gallery 2 ');var image 1=new gallery image(' image 1 . jpg ',' img 1 ');var image2=new gallery image(' image 2 . jpg ',' img 2 ');var image3=new gallery image(' image3 . jpg ',' img 3 ');var image4=new gallery image(' image4 . jpg ',' img 4 ');gallery 1 . add(image1);gallery 1 . add(image2);gallery 2 . add(image3);gallery 2 . add(image4);container . add(gallery 1);container . add(gallery 2);//确保将顶部容器添加到主体中,//否则它永远不会出现。appendo(' body ');container . show();组合模式的好处:简单的操作也能产生复杂的结果,只需对顶层对象执行操作,让每个子对象自行传递操作即可。这对于重复的操作特别有用。

在组合模式下,对象之间的耦合非常松散。只要他们实现相同的接口,改变他们的位置或交换他们只是一点点努力。促进代码的重用,也有利于代码重构。

每当对顶层复合对象执行一个操作时,实际上是对整个结构进行深度优先搜索来查找节点,但是创建复合对象的程序员对这些细节一无所知。在这个层次结构中添加、删除和查找节点非常容易。

组合模式的缺点:组合对象的易用性可能掩盖了它支持的每个操作的成本。因为复合对象调用的任何操作都会转移到它的所有子对象,如果这个层次很大,系统的性能就会受到影响。合成模式的正常操作需要某种形式的接口。

当复合对象和节点类被用作HTML元素的包装工具时,复合对象必须遵守HTML的使用规则。例如,很难将表转换成复合对象。

接口越严格,复合对象类就越可靠。

版权声明:组合模式在设计模式中的应用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。