合成(composite)模式
2016-07-18 10:04
260 查看
合成模式属于对象的结构模式,有时又叫做“部分——整体”模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。
View Code
可以看出,客户端无需再区分操作的是树枝对象(Composite)还是树叶对象(Leaf)了;对于客户端而言,操作的都是Component对象。
这里所说的透明性合成模式是指:从客户端使用合成模式上,是否需要区分到底是“树枝对象”还是“树叶对象”。如果是透明的,那就不用区分,对于客户而言,都是Compoent对象,具体的类型对于客户端而言是透明的,是无须关心的。
对于合成模式而言,在安全性和透明性上,会更看重透明性,毕竟合成模式的目的是:让客户端不再区分操作的是树枝对象还是树叶对象,而是以一个统一的方式来操作。而且对于安全性的实现,需要区分是树枝对象还是树叶对象。有时候,需要将对象进行类型转换,却发现类型信息丢失了,只好强行转换,这种类型转换必然是不够安全的。因此在使用合成模式的时候,建议多采用透明性的实现方式。
合成模式
合成模式把部分和整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由它们复合而成的合成对象同等看待。比如,一个文件系统就是一个典型的合成模式系统。下图是常见的计算机XP文件系统的一部分。//@类说明 :抽象构件角色类 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("对象不支持此功能"); } } //@类说明 :树枝构件角色类,此类将implements Conponent改为extends Conponent,其他地方无变化。 public class Composite extends Component { 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; } @Override public void printStruct(String preStr) { // 先把自己输出 System.out.println(preStr + "+" + this.name); // 如果还包含有子组件,那么就输出这些子组件对象 if (this.childComponents != null) { // 添加两个空格,表示向后缩进两个空格 preStr += " "; // 输出当前对象的子对象 for (Component c : childComponents) { // 递归输出每个子对象 c.printStruct(preStr); } } } } // @类说明 :树叶构件角色类,此类将implements Conponent改为extends Conponent,其他地方无变化。 public class Leaf extends Component { private String name; // 输出组建自身的名称 public Leaf(String name) { this.name = name; } @Override public void printStruct(String preStr) { // TODO Auto-generated method stub System.out.println(preStr + "-" + name); } } //客户端类的主要变化是不再区分Composite对象和Leaf对象。 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(""); } }
View Code
可以看出,客户端无需再区分操作的是树枝对象(Composite)还是树叶对象(Leaf)了;对于客户端而言,操作的都是Component对象。
两种实现方法的选择
这里所说的安全性合成模式是指:从客户端使用合成模式上看是否更安全,如果是安全的,那么就不会有发生误操作的可能,能访问的方法都是被支持的。这里所说的透明性合成模式是指:从客户端使用合成模式上,是否需要区分到底是“树枝对象”还是“树叶对象”。如果是透明的,那就不用区分,对于客户而言,都是Compoent对象,具体的类型对于客户端而言是透明的,是无须关心的。
对于合成模式而言,在安全性和透明性上,会更看重透明性,毕竟合成模式的目的是:让客户端不再区分操作的是树枝对象还是树叶对象,而是以一个统一的方式来操作。而且对于安全性的实现,需要区分是树枝对象还是树叶对象。有时候,需要将对象进行类型转换,却发现类型信息丢失了,只好强行转换,这种类型转换必然是不够安全的。因此在使用合成模式的时候,建议多采用透明性的实现方式。
相关文章推荐
- BlocksKit源码分析(一)
- js对字符串加密,解密
- 深入理解SELinux SEAndroid
- Android自定义字体
- [置顶] 并查集详解 (转)
- Unity内存分析器
- swift 中的 感叹号 问号 和 双问号用法详解
- FZU 2082 过路费(树链剖分)
- 《linux学习》之安装软件
- the user operation is waiting
- photoshop cs6 mac版
- tomcat安装不成功问题
- 关于算法递归的总结
- Android中的网络管理源码分析--netd
- 创业15
- hdu-5720 Wool(区间并+扫描线)
- OSChina 周一乱弹 —— 济南源创会特刊
- 类和对象的区别
- 如何解决ajax跨域问题
- iOS APP上架教程