头图

将对象组合成树状结构以表示整个部分的层次结构,组合模式可以让用户统一对待单个对象和对象组合。

组合模式一般可以分三个角色

  • 抽象组件:定义需要实现的统一操作
  • 组合节点:一个可以包含多个对象的复合对象,意味着它下面可能还会有其它组合节点和叶子节点
  • 叶子节点:下面不会有其它节点(与组合几点唯一的差距就是没有子节点)

组合模式最常用的就是用来表示一些树形结构的对象关系,就比如说部门或者员工之间的上下级关系。

下面通过员工上下级关系的例子来实现一个组合模式

抽象组件,里面定义了一些节点的共同属性和方法

public abstract class AbstractNode {
    private String name;
    private AbstractNode parent;

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

    public AbstractNode getParent() {
        return parent;
    }

    public void setParent(AbstractNode parent) {
        this.parent = parent;
    }

    public String getName(){
        return name;
    }

    public abstract void addChild(AbstractNode node);
    public abstract AbstractNode getChild(int i);
    public abstract void removeChild(int i);

    /**
     * 员工自我介绍
     */
    public abstract void introduce();

    /**
     * 团队统计
     */
    public abstract int teamCount();
}

组合节点相当于领导层,它们下面会管理一些员工

public class Node extends AbstractNode{
    private List<AbstractNode> nodes;
    public Node(String name) {
        super(name);
        nodes = new ArrayList<>();
    }

    @Override
    public void addChild(AbstractNode node) {
        node.setParent(this);
        nodes.add(node);
    }

    @Override
    public AbstractNode getChild(int i) {
        return nodes.get(i);
    }

    @Override
    public void removeChild(int i) {
        nodes.remove(i);
    }

    @Override
    public void introduce() {
        String parentName = getParent()==null?" null":getParent().getName();
        System.out.println("I am "+getName()+",my parent is "+parentName+
        ",I have "+nodes.size()+" child.");
        for (AbstractNode node:nodes) {
            node.introduce();
        }
    }

    @Override
    public int teamCount() {
        int count = 0;
        for (AbstractNode node:nodes) {
           count += node.teamCount();
        }
        return count + 1;
    }


}

叶子节点,相当于底层员工,它们相随与组合节点更加简单

public class Leaf extends AbstractNode{
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void addChild(AbstractNode node) {
        throw new RuntimeException("这是叶子节点");
    }

    @Override
    public AbstractNode getChild(int i) {
        throw new RuntimeException("这是叶子节点");
    }

    @Override
    public void removeChild(int i) {
        throw new RuntimeException("这是叶子节点");
    }

    @Override
    public void introduce() {
        System.out.println("I am "+getName()+",my parent is "+getParent().getName()+".");
    }

    @Override
    public int teamCount() {
        return 1;
    }
}

客户端调用

public class Client {
    public static void main(String[] args) {
        AbstractNode head = new Node("大领导");
        AbstractNode midA = new Node("小领导A");
        AbstractNode midB = new Node("小领导B");
        AbstractNode staff1 = new Leaf("员工-1");
        AbstractNode staff2 = new Leaf("员工-2");
        AbstractNode staff3 = new Leaf("员工-3");

        head.addChild(midA);
        head.addChild(midB);
        midA.addChild(staff1);
        midA.addChild(staff2);
        midB.addChild(staff3);

        head.introduce();
        System.out.println(head.getName()+"一共领导"+head.teamCount()+"人");
        System.out.println(midA.getName()+"一共领导"+midA.teamCount()+"人");

    }
}
==========结果==========
I am 大领导,my parent is  null,I have 2 child.
I am 小领导A,my parent is 大领导,I have 2 child.
I am 员工-1,my parent is 小领导A.
I am 员工-2,my parent is 小领导A.
I am 小领导B,my parent is 大领导,I have 1 child.
I am 员工-3,my parent is 小领导B.
大领导一共领导6人
小领导A一共领导3人

组合模式的主要目的是可以通过对象之间的组合关系把一组对象当作一个整体,统一操作。


eacape
205 声望8 粉丝

JAVA 攻城狮


« 上一篇
门面模式
下一篇 »
享元模式