设计模式笔记之八 (组合模式)

组合模式

组合模式也叫部分-整体模式,通常用来解决树形结构的问题,这种模式使树形结构中的节点和分支一致,即有相似的接口。

好吧,还是那句话:我并不关心这些个模式,哥只关心我们实验室的盈利能力和成本控制。

随着我们实验室不断的扩大,管理起来也越来越不方便了,所以老总们希望我们能有一套管理系统来管理我们实验室。

于是我们又开会来讨论这套管理系统的方案。

首先是我们的老总介绍了实验室的组织架构:

实验室总部
----总部正常人工厂
----总部财务部
----总部市场部
----泰国分部
--------泰国人妖工厂
--------泰国财务部
--------泰国市场部
----太阳国分部
--------太阳兽人工厂
--------太阳财务部
--------太阳市场部
--------洞经办事处
------------洞经财务部
------------洞经市场部

老总的女秘书抱怨道,现在所有的部门的报告都得我一一去叫,然后我再整理好发给老总,但是我完全没时间和精力做这些的啊,我服务老总才是主要职责,这些小事花了我很多时间,我哪有时间做别的阿。下面是现行的管理方案:

package com.pattern.composite;

abstract class Zuzhi { //因为报告的行为类似,所以抽成共通方法来复用
    public abstract String getName();
    public void report() {
        System.out.println("这是" + getName() + "的报告.");
    }
}

class ZongBu extends Zuzhi {
    public String getName() {
        return "实验室总部";
    }
}

class RenFactory extends Zuzhi {
    public String getName() {
        return "正常人工厂";
    }
}

class ZongBuCaiWuBu extends Zuzhi {
    public String getName() {
        return "总部财务部";
    }
}

class ZongBuShiChangBu extends Zuzhi {
    public String getName() {
        return "总部市场部";
    }
}

class TaiYangFenBu extends Zuzhi {
    public String getName() {
        return "太阳分部";
    }
}

class DongJingBanShiChu extends Zuzhi {
    public String getName() {
        return "洞经办事处";
    }
}

class DongJingShiChangBu extends Zuzhi {
    public String getName() {
        return "洞经市场部";
    }
}

// 部门实在太多, 春秋笔法下~~

class NvMiShu { // 还记得吗? 我们三个老总共用一个女秘书
    private static NvMiShu miShu;
    private static final Object o = new Object();

    private NvMiShu() {
    }

    public static NvMiShu getInstance() {
        if (miShu == null) {
            synchronized (o) {
                if (miShu == null) {
                    miShu = new NvMiShu();
                }
            }
        }
        return miShu;
    }

    public void fuWuLaoZong(String laozong) { // 对于女秘书和老总来说,这个才是最主要的功能
        System.out.println("服务老总吃: " + laozong);
        System.out.println("服务老总喝: " + laozong);
        System.out.println("服务老总拉: " + laozong);
        System.out.println("服务老总撒: " + laozong);
        System.out.println("服务老总其他: " + laozong);
    }

    public void report() { // 这是个次要功能,却占用了女秘书更多的时间
        new ZongBu().report();
        System.out.print("----");// 秘书不仅要收集报告,还得整理好才能给老总看
        new RenFactory().report();
        System.out.print("----");
        new ZongBuCaiWuBu().report();
        System.out.print("----");
        new ZongBuShiChangBu().report();
        System.out.print("----");
        new TaiYangFenBu().report();
        System.out.print("--------");
        new DongJingBanShiChu().report();
        System.out.print("------------");
        new DongJingShiChangBu().report();
    }
}

public class Composite {
    public static void main(String[] args) {
        NvMiShu.getInstance().report(); // 老总听取女秘书的报告
    }
}

以下是秘书整理好的报告

这是实验室总部的报告.
----这是正常人工厂的报告.
----这是总部财务部的报告.
----这是总部市场部的报告.
----这是太阳分部的报告.
--------这是洞经办事处的报告.
------------这是洞经市场部的报告.

老总说女秘书确实不应该花太多的时间在收集报告这种小事上,你们要弄出个解决方案出来。今天想不出来就别回去了,说完带着女秘书走了。

老总走后,我们一致觉得就是女秘书在老总面前说收集报告花了太多时间了,在其他的服务方面没时间才会有管理系统改进这件事情的。既然女秘书不想整理那么多的报告,我们就让上级部门在报告的时候把下级部门的报告一起整理好一起报告好了:

abstract class Zuzhi { //因为报告的行为类似,所以抽成共通方法来复用
    public abstract String getName();
    public void report() {
        System.out.println("这是" + getName() + "部门的报告.");
    }
}

class ZongBu extends Zuzhi {
    public String getName() {
        return "实验室总部";
    }
    public void report() {//各部门比较凄凉了,不仅要报告本部门的报告,还得收集下级部门的报告
        super.report();//报告本部门报告
        System.out.print("----");
        new RenFactory().report();//报告下级部门报告
        System.out.print("----");
        new ZongBuCaiWuBu().report();
        System.out.print("----");
        new ZongBuShiChangBu().report();
        System.out.print("----");
        new TaiYangFenBu().report();
    }
}

class RenFactory extends Zuzhi {
    public String getName() {
        return "正常人工厂";
    }

    public void report() {
        super.report();
        // 下级部门的报告
    }
}

class ZongBuCaiWuBu extends Zuzhi {
    public String getName() {
        return "总部财务部";
    }
}

class ZongBuShiChangBu extends Zuzhi {
    public String getName() {
        return "总部市场部";
    }
}

class TaiYangFenBu extends Zuzhi {
    public String getName() {
        return "太阳分部";
    }

    public void report() {
        super.report();
        System.out.print("--------");
        new DongJingBanShiChu().report();
    }
}

class DongJingBanShiChu extends Zuzhi {
    public String getName() {
        return "洞经办事处";
    }
    public void report() {
        super.report();
        System.out.print("------------");
        new DongJingShiChangBu().report();
    }
}

class DongJingShiChangBu extends Zuzhi {
    public String getName() {
        return "洞经市场部";
    }
}

// 部门实在太多, 春秋笔法下~~

class NvMiShu { // 还记得吗? 我们三个老总共用一个女秘书
    private static NvMiShu miShu;
    private static final Object o = new Object();

    private NvMiShu() {
    }

    public static NvMiShu getInstance() {
        if (miShu == null) {
            synchronized (o) {
                if (miShu == null) {
                    miShu = new NvMiShu();
                }
            }
        }
        return miShu;
    }

    public void fuWuLaoZong(String laozong) { // 对于女秘书和老总来说,这个才是最主要的功能
        System.out.println("服务老总吃: " + laozong);
        System.out.println("服务老总喝: " + laozong);
        System.out.println("服务老总拉: " + laozong);
        System.out.println("服务老总撒: " + laozong);
        System.out.println("服务老总其他: " + laozong);
    }

    public void report() { //女秘书这下轻松了
        new ZongBu().report();
    }
}

public class Composite {
    public static void main(String[] args) {
        NvMiShu.getInstance().report(); // 老总听取女秘书的报告
    }
}

这个方案提出后,女秘书果然满意了很多,但是一段时间后,总部决定将调整公司的组织架构,将太阳兽人工厂变成总部直辖,太阳分部不再管理兽人工厂了。这下各个部门都凌乱了,刚刚习惯的工作流程又被打乱了,总部的人经常忘记去要兽人工厂的报告,而太阳分部去要兽人工厂的报告的时候却被指责越界了:我现在和你平级了,你凭什么要我的报告。

好在我们的资深顾问(为什么每次都有个资深顾问,因为我们的资深顾问叫做林彪,和“四人帮”的林彪同名)又提出了一个新的解决方案:

对于女秘书来说她不关心你这个部门是处于哪个级别,有没有下属部门,她只需要你能够提供报告,并且报告的时候还包含下级部门的报告。我们可以用组合模式来解决这个问题:

import java.util.ArrayList;
import java.util.Iterator;

class Zuzhi {
    private String name;

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

    private ArrayList<Zuzhi> children = new ArrayList<Zuzhi>();

    public void addChild(Zuzhi zz) {
        children.add(zz);
    }

    public void remove(Zuzhi zz) {
        int index = children.indexOf(zz);
        children.remove(index);
    }

    public void report(String tab) {
        if (tab == null) {
            tab = "";
        }
        System.out.print(tab);
        System.out.println("这是" + name + "的报告.");
        Iterator<Zuzhi> childrenIt = children.iterator();
        while (childrenIt.hasNext()) {
            childrenIt.next().report(tab + "----");
        }
    }
}

class NvMiShu { // 还记得吗? 我们三个老总共用一个女秘书
    private static NvMiShu miShu;
    private static final Object o = new Object();

    private NvMiShu() {
    }

    public static NvMiShu getInstance() {
        if (miShu == null) {
            synchronized (o) {
                if (miShu == null) {
                    miShu = new NvMiShu();
                }
            }
        }
        return miShu;
    }

    public void fuWuLaoZong(String laozong) { // 对于女秘书和老总来说,这个才是最主要的功能
        System.out.println("服务老总吃: " + laozong);
        System.out.println("服务老总喝: " + laozong);
        System.out.println("服务老总拉: " + laozong);
        System.out.println("服务老总撒: " + laozong);
        System.out.println("服务老总其他: " + laozong);
    }

    public Zuzhi getZuzhi() {
        Zuzhi zb = new Zuzhi("实验室总部");
        Zuzhi rengc = new Zuzhi("正常人工厂");
        Zuzhi zbcw = new Zuzhi("总部财务部");
        Zuzhi zbsc = new Zuzhi("总部市场部");
        Zuzhi tyfb = new Zuzhi("太阳分部");
        Zuzhi tysrgc = new Zuzhi("太阳兽人工厂");
        Zuzhi djbsc = new Zuzhi("洞经办事处");
        Zuzhi djscb = new Zuzhi("洞经市场部");
        // 部门实在太多, 春秋笔法下~~
        zb.addChild(rengc);
        zb.addChild(zbcw);
        zb.addChild(zbsc);
        zb.addChild(tyfb);
        zb.addChild(tysrgc); // 将“太阳兽人工厂”设置成总部的下属机构
        tyfb.addChild(djbsc);
        djbsc.addChild(djscb);

        return zb;
    }

    public void report() { // 女秘书这下轻松了
        getZuzhi().report(null);// 女秘书只要设置一次公司的组织架构后,都能很容易的得取报告了。
    }
}

public class Composite {
    public static void main(String[] args) {
        NvMiShu.getInstance().report(); // 老总听取女秘书的报告
    }
}

现在终于一劳永逸的解决老总女秘书的麻烦了,就算组织架构变了,女秘书只需要重新设置下就行,不再需要各个部门忙上忙下。女秘书也不用整理杂乱无章的报告了。

至此,老总过上了女秘书专心服务的幸福生活了。

posted @ 2013-05-16 16:25  biglaojiang  阅读(490)  评论(0编辑  收藏  举报