设计模式[11]-组合模式-Composite Pattern

1. 组合模式简介

组合模式(Composite Pattern)是结构性设计模式,又叫“部分-整体”模式,主要用于树形结构的处理。父节点是整体,子节点是父节点的部分,它们具有相似的行为。

组合模式的角色一共有三种。

  • Leaf(叶节点角色): 叶子节点,即没有字节点的节点,本模式中的“部分”角色,例如文件系统中文件。

  • Composite(枝节点角色):枝节点,即本模式中的“整体”角色,它包含子节点,字节点既可以是枝节点,也可以是叶节点;例如文件系统中的文件夹。

  • Component(抽象组件角色): 是组合模式中Composite和Leaf共同的父接口(抽象类),在此接口中声明所有子类的共有的方法。

2. 组合模式举例

公司有部门和员工,可以形成一个树形结构,如果有一份通知要下发个全部的部门,或者某个事业部,需要选中对应的节点,即可完成对该节点所有子节点的通知。

序号 类名 角色 说明
1 Node Component 抽象组件角色,抽象节点
2 Staff Leaf 叶节点角色,员工
3 OrgNode Composite 枝节点角色,部门(公司、事业部)
4 CompisteMain 客户端 演示调用,通知发布
设计模式[11]-组合模式-Composite Pattern_第1张图片
Paste_Image.png

1. Node类

// 抽象组件,抽象的组织结构节点
public interface Node {
    // 增加子节点
    void add(Node node);
    // 移除子节点
    void remove(Node node);
    // 获取第i个子节点
    Node get(int i);
    // 发布通知
    void inform(String information);
}

2. Staff类

// 叶节没有子节点,因此它实现的add、remove等方法抛出异常。
public class Staff implements Node {

    private String name;

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

    @Override
    public void add(Node node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void remove(Node node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Node get(int i) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void inform(String information) {
        System.out.println("员工 [" + name + "] 收到通知:" + information);
    }
}

3. OrgNode

// 枝节点角色
public class OrgNode implements Node {

    private String name;

    private List nodeList = new ArrayList<>();

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

    @Override
    public void add(Node node) {
        nodeList.add(node);
    }

    @Override
    public void remove(Node node) {
        nodeList.remove(node);
    }

    @Override
    public Node get(int i) {
        Node node = null;
        if (i >= 0 && i < nodeList.size()) {
            node = nodeList.get(i);
        }
        return node;
    }
    // 递归调用
    @Override
    public void inform(String information) {
        System.out.println("机构 [" + name + "] 收到通知:" + information);
        for (Node node : nodeList) {
            node.inform(information);
        }
    }
}

4. CompositeMain

public class CompisteMain {

    public static void main(String[] args) {
        Node com = new OrgNode("公司");
        Node market = new OrgNode("市场部");
        Node rd = new OrgNode("研发部");
        Node ceo = new Staff("ceo 王");
        com.add(market);
        com.add(rd);
        com.add(ceo);

        Node steve = new Staff("史蒂夫");
        market.add(steve);

        Node james = new Staff("詹姆斯");
        Node vince  = new Staff("文斯");
        rd.add(james);
        rd.add(vince);

        String infomation = " 1 + 1 = 2  ";
        com.inform(infomation);
    }
}

输出结果:

机构 [公司] 收到通知: 1 + 1 = 2  
机构 [市场部] 收到通知: 1 + 1 = 2  
员工 [史蒂夫] 收到通知: 1 + 1 = 2  
机构 [研发部] 收到通知: 1 + 1 = 2  
员工 [詹姆斯] 收到通知: 1 + 1 = 2  
员工 [文斯] 收到通知: 1 + 1 = 2  
员工 [ceo 王] 收到通知: 1 + 1 = 2  

3. 组合模式总结

组合模式非常适合树形结构的处理,当要求父节点和子节点具有相同的功能的时候。

但Leaf中实现了不必要的方法,客户端不知道操作的节点是Leaf还是Composite,可能导致不安全。

如果抽象组件(例如本例的Node)中仅定义inform方法,而把add、remove、get等放入Composite类中,那么可以避免上述不安全问题;但客户端需要就要区分Leaf和Composite了。

(完)

你可能感兴趣的:(设计模式[11]-组合模式-Composite Pattern)