Composite Pattern —— Structure Class

发布时间 2023-08-30 16:00:36作者: Mysticbinary

说实话,我也没想到这个模式能在哪里运用上,暂时只是Demo理解阶段。

What is Composite Pattern

Composite Pattern(组合模式)也叫叉数、对象树、Object Tree、...。它的思想很类似自然界的树状结构。

树状结构很有意思的地方在于,每个树枝都是一样的,甚至叶子和树枝都是一样的,区别只是在于树叶下面没有树叶了。
组合模式就是借鉴了这个思想,它允许将对象组合成树状结构,并以统一的方式处理对象及对象组合。组合模式使得客户端可以一致地对待单个对象和对象组合,无需区分它们的差异。

关键要素

  • leaf and branch interface
  • leaf
  • branch
  • Client

Example —— 读取文件夹和文件

假设我们要设计一个文件系统的结构,包括文件和文件夹。文件夹可以包含文件和其他文件夹,而文件没有子组件。我们可以使用组合模式来实现这个文件系统结构。

leaf and branch interface

public interface FileSystemComponent {
    void showInfo();
}

leaf and folder

public class File implements FileSystemComponent {
    private String name;
    
    public File(String name) {
        this.name = name;
    }
    
    public void showInfo() {
        System.out.println("File: " + name);
    }
}


public class Folder implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> components;
    
    public Folder(String name) {
        this.name = name;
        this.components = new ArrayList<>();
    }
    
    public void addComponent(FileSystemComponent component) {
        components.add(component);
    }
    
    public void removeComponent(FileSystemComponent component) {
        components.remove(component);
    }
    
    public void showInfo() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent component : components) {
            component.showInfo();
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        // 创建文件和文件夹
        FileSystemComponent file1 = new File("file1.txt");
        FileSystemComponent file2 = new File("file2.doc");
        
        Folder folder1 = new Folder("Folder 1");
        Folder folder2 = new Folder("Folder 2");
        
        // 组合文件和文件夹
        folder1.addComponent(file1);
        folder1.addComponent(file2);
        folder1.addComponent(folder2);
        
        // 显示文件系统结构
        folder1.showInfo();
    }
}

out :

Folder: Folder 1
File: file1.txt
File: file2.doc
Folder: Folder 2

通过组合模式,我们可以将文件和文件夹组织成树状结构,使用统一的方式处理它们。
客户端可以递归地遍历文件系统的组件,无需关心是单个文件还是文件夹。这样,组合模式提供了一种灵活且可扩展的方式来处理对象的组合关系。

Example —— 统计城市人口数

这个案例不是那么恰当。令人费解!

interface

public interface Counter {

    int count();
}

leaf

public class Leaf implements Counter {

    private int sum = 0;

    public Leaf(int sum) {
        this.sum = sum;
    }

    @Override
    public int count() {
        return sum;
    }
}

Branch

public class Branch implements Counter {

    private List<Counter> counterList = new ArrayList<>();

    public void add(Counter counter) {
        counterList.add(counter);
    }

    public void delete(Counter counter) {
        counterList.remove(counter);
    }

    public List<Counter> getChild() {
        return counterList;
    }

    @Override
    public int count() {
        int sum = 0;
        for (Counter counter : counterList) {
            sum += counter.count();
        }
        return sum;
    }
}

Client

public class Client {
    public static void main(String[] args) {
        System.out.println("开始统计人数");
        Branch nation = new Branch();
        nation.add(new Leaf(100)); // 模拟国家下 —— 直辖市1
        nation.add(new Leaf(200)); // 模拟国家下 ——— 直辖市2

        Branch region = new Branch();
        region.add(new Leaf(300)); // 模拟国家下 —— 区1
        region.add(new Leaf(400)); // 模拟国家下 —— 区2

        nation.add(region);  // 区加入国家
        System.out.println(nation.count()); //1000
    }
}