设计模式 --- 组合模式

1.定义

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

2.使用场景

表示对象的整体-部分层次结构时

从一个整体能够独立出部分模块或功能的场景

3.简单实现

以操作系统的文件系统为例。

//抽象文件和文件夹
abstract class Dir{
    //存储文件夹下的所有文件
    List<Dir> list = new ArrayList<>();
    private String name;//文件或者文件夹名称
    public Dir(String name){
        this.name = name;
    }

    //添加文件或文件夹
    abstract void addDir(Dir dir);
    //移除文件或文件夹
    abstract void removeDir(Dir dir);
    //清空文件夹下所有元素
    abstract void clear();
    //输出文件夹结构目录
    abstract void print();
    //获取文件夹下所有的文件夹或文件
    abstract List<Dir> getFiles();
    //获取文件或文件夹名称
    public String getName() {
        return name;
    }
}

//文件夹
class Folder extends Dir{

    public Folder(String name) {
        super(name);
    }

    @Override
    void addDir(Dir dir) {
        list.add(dir);
    }

    @Override
    void removeDir(Dir dir) {
        list.remove(dir);
    }

    @Override
    void clear() {
        list.clear();
    }

    @Override
    void print() {
        System.out.print(getName() + " ( ");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Dir dir = (Dir) iterator.next();
            dir.print();
            if (iterator.hasNext()){
                System.out.print(" , ");
            }
        }
        System.out.print(" ) ");
    }

    @Override
    List<Dir> getFiles() {
        return list;
    }
}

//文件
class File extends Dir{

    public File(String name) {
        super(name);
    }

    @Override
    void addDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }

    @Override
    void removeDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }

    @Override
    void clear() {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }

    @Override
    void print() {
        System.out.print(getName());
    }

    @Override
    List<Dir> getFiles() {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }
}

public class ComponentMode {
    public static void main(String[] args){
        //构造一个目录对象表示"C"盘
        Dir dirC = new Folder("C:");
        //添加一个文件
        dirC.addDir(new File("IamFile.exe"));
        //添加三个文件夹
        Dir FolderA = new Folder("FolderA");
        dirC.addDir(FolderA);
        Dir FolderB = new Folder("FolderB");
        dirC.addDir(FolderB);
        Dir FolderC = new Folder("FolderC");
        dirC.addDir(FolderC);
        //A目录下2个文件
        FolderA.addDir(new File("aaa.txt"));
        FolderA.addDir(new File("aaa2.txt"));
        //C目录下一个文件
        FolderC.addDir(new File("ccc.txt"));

        //输出目录结构
        dirC.print();

    }
}

输出:

4.小结

优点:

组合模式可以清楚定义分层次的复杂对象,表示对象的全部或者部分层次,它让高层模块忽略了层次差异,方便对整个层次结构控制。

高层模块可以一致地使用一个组合结构或者其中单个对象,不必关系处理的是单个对象还是整个组合结构,简化了高层模块的代码。

在组合模式中增加新的枝干结构和叶子构件很方便,无需对现有类库进行任何修改。

对树形结构面向对象提供了一种灵活的解决方案,通过递归可以形成复杂的树形结构,但对树形结构的控制确非常简单。

缺点:

在新增构件时不好对枝干中的构件类型进行限制,必须进行类的检查来实现,现实过程比较复杂。

猜你喜欢

转载自blog.csdn.net/huxing0215/article/details/84325214