合成模式
合成模式属于对象的结构模式,有时又叫做“部分--整体”模式。合成模式将对象组织到树结构中国,可以用来描述整体与部分的关系,合成模式可以使客户端将单纯元素与复合元素同等看待;
涉及到三个角色;
抽象构件:这就相当于一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象,
树叶构件角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为;
树枝构件角色:代表参加组合的有下级子对象的对象,树枝构件类给出了所有的管理子对象的方法;
对于安全模式和透明模式来说,来者之间的区别就在于你的树叶构件角色的方法了,如果是安全模式的话,抽象构件只会提供最基本的接口方法,不会提供增删改查,而透明模式里面的抽象构件则会不管是树枝还是树叶,都提供了增删改查的功能,对于安全模式来说,你在树叶对象中不会调用到不该有的方法,显然更安全,而对于透明模式来说,你在新建对线的时候就不必分树枝还是树叶了,直接就是抽象构件new一个对象,而对于调用了树叶没拥有的方法,则会抛出异常,捕获,另外,安全模式是用接口实现的方式,而透明模式是用继承的方式;安全模式的合成模式要求管理聚集的方法值出现在树枝构件类中,而不出现在树叶构件类中。
安全模式的代码:
抽象构件;
package compositeSafe; public interface Component { public void printStruct(String preStr); }
树枝构件;
package compositeSafe; import java.util.ArrayList; import java.util.List; public class Composite implements Component{ public Composite() { // TODO Auto-generated constructor stub } private List<Component> childComponents = new ArrayList<Component>(); private String name; public Composite(String name){ this.name = name; } public void addChild(Component child){ childComponents.add(child); } public void removeChild(int index){ childComponents.remove(index); } public List<Component> getChild(){ return childComponents; } public void printStruct(String preStr){ System.out.println(preStr + "+" + this.name); if(this.childComponents != null){ preStr += " "; for(Component c: childComponents){ c.printStruct(preStr); } } } }
树叶构件;
package compositeSafe; public class Leaf implements Component{ public Leaf() { // TODO Auto-generated constructor stub } private String name; public Leaf(String name) { this.name = name; } public void printStruct(String preStr){ System.out.println(preStr + "-" + name); } }
客户端;
package compositeSafe; public class Client { public Client() { // TODO Auto-generated constructor stub } public static void main(String[] args){ Composite root = new Composite("服装"); Composite c1 = new Composite("男装"); Composite c2 = new Composite("女装"); Leaf leaf1 = new Leaf("衬衫"); Leaf leaf2 = new Leaf("夹克"); Leaf leaf3 = new Leaf("裙子"); Leaf leaf4 = new Leaf("套装"); root.addChild(c1); root.addChild(c2); c1.addChild(leaf1); c1.addChild(leaf2); c2.addChild(leaf3); c2.addChild(leaf4); root.printStruct(""); } }
而对于透明模式的话;树枝和树叶类基本不变,就是从接口实现变成了继承实现;
抽象构件;
package compositeClarity; import java.util.List; public abstract class Component { public abstract void printStruct(String preStr); public void addChild(Component child){ throw new UnsupportedOperationException("对象不支持功能"); } public void removeChild(int index){ throw new UnsupportedOperationException("对象不支持功能"); } public List<Component> getChild(){ throw new UnsupportedOperationException("对象不支持功能"); } }
客户端;
package compositeClarity; public class Client { public static void main(String[]args){ Component root = new Composite("服装"); Component c1 = new Composite("男装"); Component c2 = new Composite("女装"); Component leaf1 = new Leaf("衬衫"); Component leaf2 = new Leaf("夹克"); Component leaf3 = new Leaf("裙子"); Component leaf4 = new Leaf("套装"); root.addChild(c1); root.addChild(c2); c1.addChild(leaf1); c1.addChild(leaf2); c2.addChild(leaf3); c2.addChild(leaf4); root.printStruct(""); } }
对于合成模式而言,在安全性和透明性上,更看重透明性,毕竟合成模式的目的是:让客户端不再区分操作的是树枝对象还是树叶对象,而是以一个统一的方法来操作;
而且对于安全性的实现,需要区分的是树枝对象还是树叶对象,有时候,需要将对象进行类型转换,却发现类型信息丢失了,只好强行转换,这种类型转换必然是不够安全的。因此,我们建议多采用透明性的实现方式。