组合模式(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  都是调用同一个方法。

 

posted @ 2022-11-25 14:25  在博客做笔记的路人甲  阅读(204)  评论(0编辑  收藏  举报