设计模式记录(3.2)
第二十五章 合成模式
合成模型模式属于对象的结构模式,有时又叫做部分-整体模式。合成模式将对象组织到树结构中。可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。
合成模式的一个例子,道士的故事(从前有山又有庙的那个):
安全式和透明式的合成模式
安全方式是在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。编译通不过,就不会出现运行时期错误。
这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。
和透明方式各有优缺点,需要根据软件的具体情况做出选择。
类图如下:
代码如下:
package com.javapatterns.composite;public interface Component { Composite getComposite(); void sampleOperation();}
package com.javapatterns.composite;import java.util.Vector;import java.util.Enumeration;public class Composite implements Component{ private Vector componentVector = new java.util.Vector(); public Composite getComposite() { return this; } public void sampleOperation() { java.util.Enumeration enumeration = components(); while (enumeration.hasMoreElements()) { ((Component)enumeration.nextElement()).sampleOperation(); } } public void add(Component component) { componentVector.addElement(component); } public void remove(Component component) { componentVector.removeElement(component); } public Enumeration components() { return componentVector.elements(); } }
package com.javapatterns.composite;public class Leaf implements Component { public Composite getComposite(){ // Write your code here return null; } public void sampleOperation(){ // Write your code here }}
可以看出安全式的合成模式leaf节点没有add remove等方法。树枝节点里面有一个容器vactor里面来放下面的所有类。
透明式的合成模式
与安全模式的合成模式不同的是,透明式的合成模式要求所有的具体构建类,不论树枝构建还是树叶构建,均符合一个固定的接口。透明式的合成模式的示意图如下:

源代码如下:
package com.javapatterns.composite.transparent;import java.util.Enumeration;public interface Component{ void sampleOperation(); Composite getComposite(); void add(Component component); void remove(Component component); Enumeration components();}
package com.javapatterns.composite.transparent;import java.util.Vector;import java.util.Enumeration;public class Composite implements Component{ private Vector componentVector = new java.util.Vector(); public Composite getComposite() { return this; } public void sampleOperation() { java.util.Enumeration enumeration = components(); while (enumeration.hasMoreElements()) { ((Component)enumeration.nextElement()).sampleOperation(); } } public void add(Component component) { componentVector.addElement(component); } public void remove(Component component) { componentVector.removeElement(component); } public Enumeration components() { return componentVector.elements(); } }
package com.javapatterns.composite.transparent;import java.util.Enumeration;import java.util.Vector;public class Leaf implements Component{ private Vector componentVector = new java.util.Vector(); public void sampleOperation() { // Write your code here } public void add(Component component) { componentVector.addElement(component); } public void remove(Component component) { componentVector.removeElement(component); } public Composite getComposite() { // Write your code here return null; } public Enumeration components() { // Write your code here return null; } }
一个绘图的例子
安全式合成模式:

透明式合成模式:

picture是要画的类,其他的line等是叶子节点。
在下面的情况下应该考虑使用合成模式
1.需要描述对象的部分和整体的等级结构。
2.需要客户端忽略掉个体构件和组合构件的区别。客户端必须平等对待多有的构件,包括个体构件和组合构件。
3.合成模式可以很容易地增加新种类的构件。
4.使用合成模式可以使客户端变得很容易设计,因为客户端不需要知道构件是树叶构建还是树枝构建。
缺点:
使用合成模式后,控制树枝构件的类型就不太容易。
用集成的方法来增加新的行为很困难。