设计模式系列22---局部与整体的组合模式

enter image description here

今天要说的是结构模式的最后一个,组合模式。

他和我们的数据结构里面的树有点关系,怎么个关系?

还记得我们在讲 设计模式4---对外包办的门面模型的案例提到的老板叫总经理干活,实际是下面别的部门的人在干活的案例吗?

现在我们来写一个基于组合模型的总经理叫各部门人员干活的过程。

代码实现

我们定义下基础的抽象类

public abstract class Component {

    private String name;
    private String position;

    public abstract void operation();

    public Component(String name, String position) {

        this.name = name;
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public String getPosition() {
        return position;
    }
}

我们先抽象出一个组建类,这个是基础,我们的总有个名字和部门,同时还要干活operation吧。

我们看下我们的部门类:

public class BranchComponent extends Component {

    private List<Component> componentList = new ArrayList<>();

    public BranchComponent(String name, String position) {
        super(name, position);
    }

    @Override
    public void operation() {
        System.out.print(this.getPosition() + "部门都在干活");
    }

    public void addComponent(Component component) {
        componentList.add(component);
    }

    public void removeComponent(Component component) {
        componentList.remove(component);
    }

    public List<Component> getComponentList() {
        return componentList;
    }

}

部门当然要有员工在里面啦,所以我们有一个componentList来保存员工信息,同时配套一些函数来增加员工addComponent,开除偷懒的removeComponent

接着看下我们的员工类

public class LeafComponent extends Component {

    public LeafComponent(String name, String position) {
        super(name, position);
    }

    @Override
    public void operation() {

        System.out.println("部门"+this.getPosition()+ "员工"+this.getName()+" 正在干活");
    }
}

他的内容就是干活,没什么好好说的。
但不一样的是,我们的员工是树的”叶子“,所以他没别的了,不能添加内容,不像部门是一个”分支点”,可以加内容。

有了这些准备我们可以来写测试的情况了
相对平常的有点长,因为要生成一些mock的数据。

public class Boss {

    public static void main(String[] args) {            
        BranchComponent manager = getBranchTree();
        orderToOperation(manager);
    }

    private static void orderToOperation(BranchComponent manager) {

        List<Component> componentList = manager.getComponentList();
        for (Component component : componentList) {
            if (component instanceof LeafComponent) {
                component.operation();
            } else {
                orderToOperation((BranchComponent) component);
            }
        }
    }

    private static BranchComponent getBranchTree() {

        BranchComponent manager = new BranchComponent("总经理", "总裁办");
        BranchComponent sales = new BranchComponent("销售负责人", "销售部");
        BranchComponent product = new BranchComponent("开发负责人", "产品部");

        LeafComponent pA = new LeafComponent("开发a", "开发人员");
        LeafComponent pB = new LeafComponent("开发b", "开发人员");
        LeafComponent pC = new LeafComponent("开发c", "开发人员");

        LeafComponent sA = new LeafComponent("销售a", "销售人员");
        LeafComponent sB = new LeafComponent("销售a", "销售人员");
        LeafComponent sC = new LeafComponent("销售a", "销售人员");

        manager.addComponent(sales);
        manager.addComponent(product);

        sales.addComponent(sA);
        sales.addComponent(sB);
        sales.addComponent(sC);

        product.addComponent(pA);
        product.addComponent(pB);
        product.addComponent(pC);

        return manager;
    }
}

是不是和我们学数据结构里面的树一样?现在是在遍历二叉树的感觉?

类图

enter image description here

这个就是我们的UML类图,不过有一点要提的是,这个是叫透明模式,因为他把我们部门的加人和赶人的方法都加上去了。我们在调用这些子类的时候,都可以看到,所以叫透明模式。

如果把这几个函数移回到我们的BranchComponent去的话,就叫安全模式。他避免我们在访问的时候,如果是叶节点的时候,不会访问到这几个函数,因此安全。

当然这连个模式各有优缺,可以自己权衡。

这个组合模式的一个缺点的是,我们在使用的时候需要直接用实现类,而不是接口!

BranchComponent manager = new BranchComponent("总经理", "总裁办");
LeafComponent sC = new LeafComponent("销售a", "销售人员");

这对于习惯强调面向接口编程上来说是不好的,需要我们自己权衡。

后记

今天没有后记。

热评文章