组合模式关注那些存在于叶子构件和容器构件的结构以及它们的组织形式,叶子构件中不能包含成员对象,容器构件中能够包含成员对象,这些成员对象多是叶子构件对象,也多是容器构件对象。这些对象能够构成一个树形结构,组合模式是用面向对象的方法处理树形结构。java
在Windows操做系统的文件目录结构包含文件和文件夹两类对象,其中在文件夹能够包含子文件夹,也能够包含文件。文件夹是容器类,而不一样类型的各类文件是成员类,也称为叶子类,一个文件夹也能够做为另外一个更大的文件夹的成员。组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,能够作到一致对待容器对象和叶子对象。算法
组合多个对象造成树形结构以表示“总体-部分”的结构层次。编程
Component(抽象构件)安全
抽象构件能够是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中能够包含全部子类共有行为的声明和实现。在抽象构件在定义了访问及管理它的子构件的方法,如增长子构件、删除子构件、获取子构件等。ide
Leaf(叶子构件)操作系统
叶子构件在组合结构中表示叶子节点对象,叶子节点没有子节点,实如今抽象构件中定义的行为。对于访问及管理子构件的方法,能够经过异常等方式进行处理。设计
Composite(容器构件)code
容器构件在组合结构中表示容器节点对象,容器节点包含子节点,其子节点能够是叶子节点,也能够是容器节点,它提供一个集合用于存储子节点,实如今抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中能够递归调用其子节点的业务方法。对象
Client(客户类)blog
客户类是能够经过抽象构件接口访问和控制组合构件中的对象。
组合模式的关键是定义一个抽象构件类,它既能够表明叶子,也能够表明容器,而客户端针对该抽象构件类进行编程,无须知道它究竟是叶子仍是容器,能够对其进行统一处理。
通常抽象构件类设计为接口或抽象类,将全部子类共有方法声明和实现放在抽象构件类中。对于客户端编程,将针对抽象构件编程,而无须关心其具体子类是容器构件仍是叶子构件。
public abstract class Component { public abstract void add(Component c); public abstract void remove(Component c); public abstract Component getChild(int i); public abstract void operation(); }
继承抽象构件的是叶子构件则典型代码以下,叶子构件须要实现抽象构建类中声明的全部方法,包括业务方法以及管理和访问子构件的方法,可是叶子构件不包含子构件,所以在在客户端调用叶子构件的子构件管理和访问方法时需提供异常处理或错误提示。
public class Leaf extends Component { @Override public void add(Component c) { //异常处理或错误提示 } @Override public void remove(Component c) { //异常处理或错误提示 } @Override public Component getChild(int i) { //异常处理或错误提示 return null; } @Override public void operation() { //实现代码 } }
容器构件须要实现抽象构建类中声明的全部方法,包括具体实现业务方法以及管理和访问子构件的方法。因为容器构件充当的是容器角色,包含成员构件,所以它将调用其成员构件的业务方法,使用递归算法,即在容器构件的operation()方法中递归调用其成员构件的operation()方法。
public class Composite extends Component { private ArrayList list = new ArrayList(); @Override public void add(Component c) { list.add(c); } @Override public void remove(Component c) { list.remove(c); } @Override public Component getChild(int i) { return (Component) list.get(i); } @Override public void operation() { for (Object o : list) { ((Component) o).operation(); } } }
组合模式优势:
组合模式缺点:
在如下状况下可使用组合模式:
组合模式根据抽象构件类的定义形式,又可分为透明组合模式和安全组合模式
透明组合模式
透明组合模式中,抽象构件Component中声明全部用于管理成员对象的方法,这样作的好处是确保全部构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端能够相同地对待全部的对象。缺点是不够安全,由于叶子对象和容器对象在本质上是有区别的。
安全组合模式
安全组合模式中抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明这些用于管理成员对象的方法。对于叶子对象,客户端不可能调用到管理成员对象的方法。缺点是不够透明,客户端不能彻底针对抽象编程。