← 返回首页
设计模式基础教程(十七)
发表时间:2021-08-25 01:46:50
组合模式

1.组合模式

组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象,这就是组合模式的模式动机。

对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象,如子文件夹和文件)并调用执行。(递归调用)

由于容器对象和叶子对象在功能上的区别,在使用这些对象的客户端代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使得程序非常复杂。

2.实例

在水果盘(Plate)中有一些水果,如苹果(Apple)、香蕉(Banana)、梨子(Pear),当然大水果盘中还可以有小水果盘,现需要对盘中的水果进行遍历(吃),当然如果对一个水果盘执行“吃”方法,实际上就是吃其中的水果。使用组合模式模拟该场景。

项目结构图如下:

定义元素类

public abstract class MyElement {
    public abstract void eat();
}

定义容器类(盘子)

public class Plate extends MyElement {
    private List<MyElement> list=new ArrayList<>();
    public void add(MyElement element){
        list.add(element);
    }
    public void delete(MyElement element){
        list.remove(element);
    }
    @Override
    public void eat() {
        for(MyElement element:list){
            element.eat();
        }
    }
}

定义不同水果类

//Apple.java
public class Apple extends MyElement {
    @Override
    public void eat() {
        System.out.println("吃苹果");
    }
}

//Banana.java
public class Banana extends MyElement {
    @Override
    public void eat() {
        System.out.println("吃香蕉");
    }
}

//Pear.java
public class Pear extends MyElement {
    @Override
    public void eat() {
        System.out.println("吃梨");
    }
}

测试类

public class TestCompositeDemo01 {

    public static void main(String[] args) {
        MyElement elt1,elt2,elt3,elt4,elt5;
        Plate plate1,plate2,plate3;

        elt1=new Apple();
        elt2=new Pear();
        plate1=new Plate();

        plate1.add(elt1);
        plate1.add(elt2);

        elt3=new Banana();
        elt4=new Banana();
        plate2=new Plate();
        plate2.add(elt3);
        plate2.add(elt4);

        elt5=new Apple();
        plate3=new Plate();

        plate3.add(plate1);
        plate3.add(plate2);
        plate3.add(elt5);


        plate1.eat();
        System.out.println("====");
        plate2.eat();
        System.out.println("====");
        plate3.eat();
    }

}

运行结果:
吃苹果
吃梨
====
吃香蕉
吃香蕉
====
吃苹果
吃梨
吃香蕉
吃香蕉
吃苹果