设计模式之组合模式

123 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

组合模式是一种结构型设计模式,在 GoF 的《设计模式》一书中,组合模式是这样定义的:将一组对象组织成树形结构,以表示一种“部分 - 整体”的层次结构。组合让客户端(“客户端”代指代码的使用者。)可以统一单个对象和组合对象的处理逻辑。

组合模式跟面向对象设计中的“组合关系(通过组合来组装两个类)”,完全是两码事。这里的“组合模式”,主要是用来处理树形结构数据。

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

使用场景

数据需要表示成树形结构,比如文件的目录树,OA系统的组织架构

类图

类图

代码实现

Region

public class Region {

    private Integer id;
    private String name;
    private List<Region> subRegions;

    public Region(Integer id, String name) {
        this.id = id;
        this.name = name;
        this.subRegions = new ArrayList<>();
    }

    public void add(Region region) {
        this.subRegions.add(region);
    }

    public void remove(Region region) {
        this.subRegions.remove(region);
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<Region> getSubRegions() {
        return subRegions;
    }

    @Override
    public String toString() {
        return "Region{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

}

Main

public class Main {

    public static void main(String[] args) {
        Region beijing = new Region(1"北京市");

        Region chaoyang = new Region(2"朝阳区");
        Region haidian = new Region(3"海淀区");

        Region dongfeng = new Region(4"东风街道");
        Region jinsong = new Region(5"劲松街道");

        Region zhongguancun = new Region(6"中关村街道");

        beijing.add(chaoyang);
        beijing.add(haidian);

        chaoyang.add(dongfeng);
        chaoyang.add(jinsong);

        haidian.add(zhongguancun);

        // 递归打印
        print(beijing);
    }

    private static void print(Region region) {
        System.out.println(region);
        for (Region subRegion : region.getSubRegions()) {
            print(subRegion);
        }
    }

}

至此,我们完成了组合模式的设计,组合模式与其说是设计模式,倒不如说是一种数据结构(树结构)和算法(递归)。