一、组合模式的核心思想--树形结构
组合模式有时候又叫做部分一整体模式,它使我们在处理树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。将对象组合成树形结构以表示"部分一整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
如下图所示,TreeNode 可以包含n个TreeNode 节点对象,并可以通过 add()和 remove()来增加和删除这些对象,从而形成树,这就是组合模式的体现。
TreeNode.java 类本身就是一个组合模式类,它使用一个集合对象children 来组合它的所有孩子节点,并可以提供 parent来返回其父亲节点。其源代码如下程序所示。
树节点TreeNode.java
java
package structure.composite;
import java,util.Enumeration;
import java.util.Vector;
/**
* @author Minggg
* 合成模式
*/
public class TreeNode {
private String name;// 节点名称
private TreeNode parent;// 父节点
private Vector<TreeNode> children = new Vector<TreeNode>();// 孩子节点
public TreeNode(String name) {
this.name = name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
// 添加孩子节点
public void add(TreeNode node) {
children.add(node);
}
// 删除孩子节点
public void remove(TreeNode node) {
children.remove(node);
}
// 取得孩子节点
public Enumeration<TreeNode> getChildren() {
return children.elements();
}
}
使用该树节点我们可以构造一颗树,只需要从树根开始进行构造。例如,我们要构建如下的一棵树:
需要先创建一个A树节点,然后分别创建B、C、D、E、F、G节点,并将E加入到 B,F加入到 C,G 加入到 D,B、C、D加入到A中。其源代码如下程序所示。
树节点类实例
java
package structure.composite;
public class Tree {
TreeNode root = null;
public Tree(String name){
root = new TreeNode(name);
}
public void test() {
Tree tree = new Tree("A");
TreeNode nodeB = new TreeNode("B");
TreeNode nodeC = new TreeNode("C");
TreeNode nodeD = new TreeNode("D");
TreeNode nodeE = new TreeNode("E");
TreeNode nodeF = new TreeNode("F");
TreeNode nodeG = new TreeNode("G");
nodeB.add(nodeE);
nodeB.add(nodeF);
nodeC.add(nodeG);
tree.root.add(nodeB);
tree.root.add(nodeC);
tree.root.add(nodeD);
}
}
二、何时使用组合模式
组合模式也是一种对象的适配器模式,它将多个对象组合在一起进行操作;同时它又是一种桥接模式,它可以通过 addO和remove()方法来添加和删除多个对象,即实现了桥的功能。
根据组合模式的特点,它最常用的就是在树形结构的表示中。例如二叉树、多叉树等,通常用来表示有树形结构的数据集合。
三、Java中的应用--AWT 容器 Container
AWT提供了大量的组件和容器,包括窗体、菜单和各种输入组件。AWT类全部在java.awt包中,Java图形用户界面的最基本组成部分是组件(Component),组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如一个按钮、一个标签等。组件不能独立地显示出来,必须将组件放在一定的容器中才可以显示出来。类java.awt.Component 是许多组件类的父类,Component 类中封装了组件通用的方法和属性,如图形的组件对象、大小、显示位置、前景色和背景色、边界、可见性等。
容器java.awt.Container是Component的子类,因此容器本身也是一个组件,它具有组件的所有性质,但是它的主要功能是容纳其他组件和容器。一个容器可以容纳多个组件,并使它们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面。所有的容器都可以通过 add()方法向容器中添加组件。
因此,这里的容器类就是组件类的组合,所有的子容器类型都可以拥有多个Component的子类型对象,如下图所示。