Java设计模式--组合模式

1 Composite Pattern 组合模式

目的:将对象组合成树形结构以表示”部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性;
实现:树枝(容器)和叶子实现统一接口,树枝内部组合该接口。

1.树枝,叶子都实现一个接口,对外只呈现了一个接口;
2.树枝(容器)内部组合该接口,并且含有内部属性 List,里面放叶子;
3.树枝提供内部属性List增删的功能使节点可以自由增删;
4.节点需要有一个自己的标识,这样需要调用哪个叶子就容易判断了。

2 实现

代码场景:中国神话故事中天庭的建立与西游记中孙悟空的招安
1.众神实现一个接口;
2.玉皇大帝相当于树枝(容器),管理天庭;
3.众神相当于叶子,有自己的标识、职责,处理自己职责范围内的事。

2.1 代码实现

神仙接口

/**
 * 神仙接口 
 * 为了演示组合模式就归为一个概念了
 * 神特指凡人死后元神升天成神,仙是凡人活体飞升,神和仙不是一个概念
 */
public interface ShenXian {
    // 神仙处理问题
    void dealProblem();
    // 获取神仙职责
    String getDuty();
    // 获取神仙的名字
    String getName();
}

树枝(容器)角色:玉皇大帝

/**
 * 玉皇大帝 相当于树枝 掌管天庭人员 事物 
 * 天庭诸神 相当于叶子 听从玉帝命令
 */
public class YuDi implements ShenXian {
    private final static String name = "玉皇大帝";
    // 玉帝职责是 管理者
    private final String duty = "管理";
    // 组合模式关键所在 组合了一个神仙接口的list
    List<ShenXian> shen = new ArrayList<ShenXian>();
    @Override
    public String getDuty() {
        return duty;
    }
    // 掌管三界,统领天庭
    @Override
    public void dealProblem() {
        System.out.println("掌管三界,统领天庭");
    }
    // 招纳神仙
    public void addShen(ShenXian s) {
        shen.add(s);
        System.out.println("天庭吸收了一位新成员[" + s.getName() + "]");
    }
    // 罢免官员
    public void deleteShen(ShenXian s) {
        shen.remove(s);
        System.out.println("天庭删除了一位成员[" + s.getName() + "]");
    }
    // 对外提供 花名册
    public List<ShenXian> getShenList() {
        return shen;
    }
    @Override
    public String getName() {
        return name;
    }
}

叶子角色:太白金星

public class TaiBaiJinXing implements ShenXian {
    private final static String name = "太白金星";
    // 天白金星 职责是 和事老 调解
    private final String duty = "调解";
    @Override
    public String getDuty() {
        return duty;
    }
    @Override
    public void dealProblem() {
        System.out.println("太白金星:大事化小 小事化了~");
    }
    @Override
    public String getName() {
        return name;
    }
}

叶子角色:托塔李天王

public class TuoTaLiTianWang implements ShenXian {
    private final static String name = "托塔李天王";
    // 托塔李天王 职责是 打的你满地找牙
    private final String duty = "打";
    @Override
    public String getDuty() {
        return duty;
    }
    @Override
    public void dealProblem() {
        System.out.println("托塔李天王:我保证不打死你~");
    }
    @Override
    public String getName() {
        return name;
    }
}

叶子角色:嫦娥

public class ChangE implements ShenXian {
    private final static String name = "嫦娥";
    // 嫦娥
    private final String duty = "孤独的养着兔子";
    @Override
    public void dealProblem() {
        System.out.println("胡萝卜又没了");
    }
    @Override
    public String getDuty() {
        return duty;
    }
    @Override
    public String getName() {
        return name;
    }

}

叶子角色:孙悟空

public class SunWuKong implements ShenXian {
    private final static String name = "齐天大圣 孙悟空";
    // 弼马温 职责 养马
    private final String duty = "养马";
    @Override
    public void dealProblem() {
        System.out.println("孙悟空:你让老子给你看马 老子不干了");
    }
    @Override
    public String getDuty() {
        return duty;
    }
    @Override
    public String getName() {
        return name;
    }

}

2.2 涉及角色

在组合模式结构图中包含如下几个角色:

Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。

Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。

Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        System.out.println("剧情:天庭建立之前,诸神终日混战,三界大乱~");
        System.out.println("剧情:天庭建立,结束纷争~");
        YuDi yd = new YuDi();
        TaiBaiJinXing taiBai = new TaiBaiJinXing();
        TuoTaLiTianWang tuoTa = new TuoTaLiTianWang();
        ChangE ce = new ChangE();
        yd.addShen(taiBai);
        yd.addShen(tuoTa);
        yd.addShen(ce);
        System.out.println("剧情:等诸神纷纷被玉帝招进天庭...");
        System.out.println("-------------------");
        System.out.println("剧情:孙悟空在花果山自称\"齐天大圣\" 怎么办?");
        ShenXian tb = whoDeal(yd.getShenList(), "调解");
        tb.dealProblem();
        SunWuKong biMaWen = new SunWuKong();
        yd.addShen(biMaWen);
        biMaWen.dealProblem();
        System.out.println("剧情:孙悟空私自下凡,天庭决定动用武力...");
        ShenXian tt = whoDeal(yd.getShenList(), "打");
        tt.dealProblem();
        System.out.println("剧情:想知后事如何,且听下回分解...");
    }

    // 遍历枝干的list找到需要的那个叶子
    private static ShenXian whoDeal(List<ShenXian> shen, String how) {
        ShenXian sx = null;
        for (ShenXian s : shen) {
            if (how.equals(s.getDuty())) {
                sx = s;
            }
        }
        return sx;
    }
}

结果:

剧情:天庭建立之前,诸神终日混战,三界大乱~
剧情:天庭建立,结束纷争~
天庭吸收了一位新成员[太白金星]
天庭吸收了一位新成员[托塔李天王]
天庭吸收了一位新成员[嫦娥]
剧情:等诸神纷纷被玉帝招进天庭...
-------------------
剧情:孙悟空在花果山自称"齐天大圣" 怎么办?
太白金星:大事化小 小事化了~
天庭吸收了一位新成员[齐天大圣 孙悟空]
孙悟空:你让老子给你看马 老子不干了
剧情:孙悟空私自下凡,天庭决定动用武力...
托塔李天王:我保证不打死你~
剧情:想知后事如何,且听下回分解...

代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

猜你喜欢

转载自blog.csdn.net/weixx3/article/details/80147046