设计模式之组合模式

1、什么是组合模式

  组合模式是一种方案,能够让用户可以一致性地处理整个树形结构(容器构件)或树形结构的一部分(叶子构件)。虽然两部分表现出的功能不一样,整体使用上无太大差别。

2、组合模式应用场景

  1:在具有整体和部分的层次结构中,希望通过一种方式忽略整体和部分的差异,客户端可以一致性对待处理。

  2:处理的是一个树形结构。

  3:系统中可以分离出叶子对象和容器对象,而且他们的类型不固定,需要增加一些新的类型。

  遍历文件夹进行文件类型、数量、大小的统计。文件夹内可能包含子文件夹(容器文件),也可能只有具体格式的文件,即叶子文件。

3、组合模式示例

  首先区分一下透明式组合模式和安全型组合模式

  透明式组合模式:

    抽象构件中声明了所有用于管理成员对象的方法,确保所有构件类都有相同的接口。在客户端看来叶子构件和容器构件所提供的方法一致的。具体可参考示例

  安全型组合模式:

    抽象构件中声明构件操作的方法,叶子构件继承方法重写实现具体的操作,而在组合类中声明并实现用于管理成员对象(构件)的方法,这样叶子构件根本看不到管理成员对象的方法,避免在使用中出现异常操作。

  透明式组合示例:

  

AbstractFile --抽象构件类
/**
* @Description 抽象构件
* @CreateDate 2019-09-15-21:28
*/
public abstract class AbstractFile {
public abstract void add(AbstractFile file);
public abstract void remove(AbstractFile file);
public abstract AbstractFile getChild(int i);
public abstract void killVirus();
}
import java.util.ArrayList;

/**
 * @Description 文件容器类:容器构件
 * @CreateDate 2019-09-15-21:42
 */
public class Folder extends AbstractFile {
    private String name;
    public Folder(String name){
        this.name = name;
    }
    private ArrayList<AbstractFile> fileList = new ArrayList<>();
    @Override
    public void add(AbstractFile file) {
        fileList.add(file);
    }

    @Override
    public void remove(AbstractFile file) {
        fileList.remove(file);
    }

    @Override
    public AbstractFile getChild(int i) {
        return (AbstractFile)fileList.get(i);
    }

    @Override
    public void killVirus() {
        System.out.println("****对文件夹'" + name + "'进行杀毒");
        for (Object obj : fileList) {
            ((AbstractFile)obj).killVirus();
        }
    }
}
/**
 * @Description 文本文件类:叶子构件
 * @CreateDate 2019-09-15-21:35
 */
public class TextFile extends AbstractFile {
    private String name;
    public TextFile(String name){
        this.name = name;
    }
    @Override
    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public AbstractFile getChild(int i) {
        System.out.println("对不起,不支持该方法!");
        return null;
    }

    @Override
    public void killVirus() {
        //模拟杀毒
        System.out.println("----对文本文件'" + name + "'进行杀毒");
    }
}

客户端测试代码

/**
 * @Description TODO
 * @CreateDate 2019-09-15-21:51
 */
public class CompositeClient {
    public static void main(String[] args) {
        AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;
        folder1 = new Folder("Sunny的资料");
        folder3 = new Folder("文本文件");
        file3 = new TextFile("九阴真经.txt");
        file4 = new TextFile("葵花宝典.doc");

        folder3.add(file3);
        folder3.add(file4);
        folder1.add(folder3);
        folder1.killVirus();
    }
}

4、组合模式优缺点

优点:

  1:客户端一致的使用组合结构或单个对象,不需要关心处理的对象类别

  2:增加新的容器构件和叶子构件都很方便,无需对现有类库进行任务修改,符合“开闭原则”

  3:可以很简单的处理树形结构。

缺点:

  1:添加构件时很难对容器中的构件类进行限制。

本文参考http://gof.quanke.name/

原文地址:https://www.cnblogs.com/SmilingFish/p/11524989.html