组合模式(Composite)
把部分和整体的关系用树形结构来表示,使客户端可以使用统一的方式处理部分对象(比如具体文件)和整体对象(比如一个文件夹)。
构成:
Component 抽象角色:定义了叶子和容器结构的共同方法
Leaf 叶子角色:无子节点。
Composite 容器角色:可以包含字节点。
比如:
我要对一个文件进行查杀,调用相应的 Check 方法即可,文本文件用TextCheck、图像文件用ImageCheck.....
我要对一个文件夹进行查杀,那自然要对里面所有的、不一定相同的文件进行查杀。
通过组合模式,定义一个抽象组件abstractCheck,把不同文件的查杀实现为叶子节点,文件夹的查杀为容器节点。
即可调用统一的Check 方法进行查杀。
图解:
如图,Leaf 与 Composite 都是抽象接口 Component 的实现类。
容器角色中一般,额外包含它下面的节点,以及相应的增、删、查方法。
示例代码:
Component 抽象角色:定义了叶子和容器结构的共同方法。
public interface Component extends Cloneable{ void test(); }
Leaf 叶子角色:实现共同方法,无子节点。
class Leaf implements Component{ @Override public void test() { System.out.println("这里是叶子节点"); }
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
Composite 容器角色:实现共同方法,包含字节点,并且一般包含对子节点的的操作。
class Composite implements Component{ List<Component> nodes = new ArrayList<>();//存储子节点 @Override public void test() { System.out.println("这里是容器节点"); //递归啦!容器角色下的test方法。 for(Component c:nodes){ c.test(); } } //增加节点 public void addNode(Component c){ nodes.add(c); } //删除节点 public void removeNode(Component c){ nodes.remove(c); } //获取节点 public Component getNodes(int index) { return nodes.get(index); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
测试:
public class Client { public static void main(String[] args) throws Exception { //创建一个叶子节点。 Leaf leaf1 = new Leaf(); //通过原型模式复制3个一样的叶子节点 Leaf leaf2 = (Leaf) leaf1.clone(); Leaf leaf3 = (Leaf) leaf1.clone(); Leaf leaf4 = (Leaf) leaf1.clone(); //创建一个容器节点 Composite composite1 = new Composite(); //把叶子节点丢入容器节点 composite1.addNode(leaf1); composite1.addNode(leaf2); composite1.addNode(leaf3); composite1.addNode(leaf4); //共同的方法 composite1.test(); } }
运行结果:通过组合模式实现了:我对子节点进行 test 或者对于容器节点进行 test 都是调用同一个方法。