组合模式_[设计模式] 组合模式

组合模式(Composite Pattern)是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。我们生活中有很多这样的树状层级结构,比如公司的某个部门下面,有一些工作人员,也可能还有其它部门,电脑系统的文件夹里面除了文件外,还可能有另外的文件夹。

在这种树状模式中,有单个对象(比如每个文件),也有组合对象(比如文件夹)。组合模式能够让我们统一的处理单个对象和组合对象,无需关心自己处理的到底是哪个对象。

接下来我们用文件/文件夹这个树状结构来写示例代码,实现组合模式。

56030ceedc37cf881e1d32476144697d.png

假设我们的目标是展示display文件系统的结构。先定义一个Component接口,其中有一个display()展示方法。File文件类和Folder文件夹类都实现这个接口,用来展示文件系统中都有哪些文件或文件夹。File类很简单,有一个name名字变量,display()的方法里面仅仅是打印自己的名字。

public class File implements Component {
    String name;
    public File(String name) {
        this.name = name;
    }
    @Override
    public void display() {
        System.out.println("This is file: " + this.name);
    }
}

Folder类就是组合模式的核心思想了。文件和文件夹是一种"部分-整体"的关系,文件夹里面既可以包含文件,也可以包含文件夹,而包含的文件夹里面又可以包含文件和文件夹。若是直接在Folder类维护一个 List<> 或 List<>都无法满足要求。实际上,我们这个时候维护的是List<>这个接口的list。因为,我们的目标是展示文件结构,无论是File还是Folder都可以被放入这个list,然后调用实际对象的展示display方法。 下面是Folder类的代码:

public class Folder implements Component{
    String name;
    List<Component> children = new ArrayList<>();

    public Folder(String name) {
        this.name = name;
    }

    public void add(Component c) {
        children.add(c);
    }

    @Override
    public void display() {
        System.out.println("This is folder: " + this.name);
        for(Component component: children) {
            component.display();
        }
    }
}

在Folder中维护一个Component的list。值得注意的是,在display()方法中,除了先打印自己folder的名字之外,还需要遍历这个list,调用每个Component的display()方法。这个时候,我们就不需要关心每个Component实际上到底是Folder对象还是File对象,多态机制会最终调用到正确的方法。这就是前面说的"组合模式能够让我们统一的处理单个对象和组合对象,无需关心自己处理的到底是哪个对象"。

最后是Main方法的使用,创建了文件夹folder_a,这个文件夹下面有一个文件file_a以及另外一个文件夹folder_b; 在folder_b下面有另外两个文件file_c和file_d。我们要展示文件结构,最后只需要调用顶层文件夹folder_a的display()方法就好了。

运行结果如下:

This is folder: folder_a
This is file: file_a
This is folder: folder_b
This is file: file_b
This is file: file_c

最终结果就像dfs一样把下面所有的文件夹和文件都遍历到了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值