软件体系结构-组合模式
定义
组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。
UML类图
包含三个部分:抽象构件、叶子构件和容器构件

代码实现
抽象构件:
1 2 3 4 5 6
| public abstract class AbstractNode { public abstract void addNode(AbstractNode node); public abstract void removeNode(AbstractNode node); public abstract AbstractNode getNode(int i); public abstract void handleMessage(String msg); }
|
叶子构件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public class UserNode extends AbstractNode{
@Override public void addNode(AbstractNode node) { try { throw new Exception("UserNode不支持addNode"); } catch (Exception e) { e.printStackTrace(); } }
@Override public void removeNode(AbstractNode node) { try { throw new Exception("UserNode不支持removeNode"); } catch (Exception e) { e.printStackTrace(); } }
@Override public AbstractNode getNode(int i) { try { throw new Exception("UserNode不支持getNode"); } catch (Exception e) { e.printStackTrace(); } return null; }
@Override public void handleMessage(String msg) { System.out.println("处理消息:"+msg); } }
|
容器构件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class GroupNode extends AbstractNode{ private ArrayList<AbstractNode> nodeList = new ArrayList<AbstractNode>();
@Override public void addNode(AbstractNode node) { nodeList.add(node); }
@Override public void removeNode(AbstractNode node) { nodeList.remove(node); }
@Override public AbstractNode getNode(int i) { return nodeList.get(i); }
@Override public void handleMessage(String msg) { System.out.println("处理消息:"+msg); } }
|
透明组合与安全组合模式
透明组合模式:
- 抽象构件Component中声明了所有用于管理成员对象的方法,包括
add()、remove(),以及getChild()等方法
- 在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象
- 缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的
安全组合模式:
优点
在具体实现时,可以创建图形化界面让用户来选择所需操作的根节点,无须修改源代码,符合开闭原则
- 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制
- 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
- 增加新的容器构件和叶子构件都很方便,符合开闭原则
- 为树形结构的面向对象实现提供了一种灵活的解决方案
缺点
适用
- 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们
- 在一个使用面向对象语言开发的系统中需要处理一个树形结构
- 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型