Java设计模式之-组合模式

本文深入探讨了组合模式的概念,通过举例说明了如何将其应用于大型公司的组织结构中,详细讲解了组合模式的实现方式,并讨论了透明模式与安全模式的优缺点。最后,分析了组合模式的应用场景及优势。

组合模式

带着问题去阅读:

  • 什么是组合模式
  • 如何理解组合模式
  • 如何实现组合模式
  • 何时使用组合模式
  • 组合模式的好处

1. 什么是组合模式

组合模式(Composite) 将对象组合成树形结构以表示’部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

2. 如何理解组合模式?


设想一个大型公司的组织结构

  • 总公司:下设有分公司(组合)、财务部(单个对象)、人力资源部(单个对象)
  • 每个分公司,可能还会有子公司(组合),当然,也会设有财务部(单个对象)和人力资源部(单个对象)
  • 只要你的公司足够大,可以无限循环下去

其结构图结构图大致如下:
组织结构图.jpg


或许你已经明白,所谓组合,就是下面依然有组合或单个对象,而单个对象,之后不会再有对象了,类似一棵树,树干有树枝,树枝可能有树枝,也可能只有叶子。

3. 如何实现组合模式


先来看类图:


设计模式-组合模式.png
Component接口(当然也可以使用抽象类):

package com.aran.DesignPatterns.Composite;

/**
 * @Author Aran
 * @Date 2020/3/29 5:22 下午
 */
public interface Component {
     void add(Component component);
    void remove(Component component);
    void display(String name);
}


组合,也就是分公司

package com.aran.DesignPatterns.Composite;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author Aran
 * @Date 2020/3/29 5:25 下午
 */
public class Composite implements Component {
    List<Component> children = new ArrayList<>();




    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(String name) {
        System.out.println("hello, i'm a composite from "+name+" ,i have "+children.size()+" children now");
    }
}


叶子节点,也就是部门:

package com.aran.DesignPatterns.Composite;

/**
 * @Author Aran
 * @Date 2020/3/29 5:23 下午
 */
public class Leaf implements Component {
    @Override
    public void add(Component c) {
        System.out.println("i'm a leaf, i can't add anymore");
    }

    @Override
    public void remove(Component c) {
        System.out.println("i'm a leaf, i can't remove anymore");
    }

    @Override
    public void display(String name) {
        System.out.println("i can only display , i'm a leaf from "+name+"");
    }
}


客户端测试:

package com.aran.DesignPatterns.Composite;

/**
 * @Author Aran
 * @Date 2020/3/29 5:29 下午
 */
public class Main {
    public static void main(String[] args) {
        //北京总公司
        Component bj = new Composite();

        //上海分公司
        Component sh = new Composite();

        //杭州分公司
        Component hz = new Composite();

        //财务部
        Component financialDepart_BJ = new Leaf();

        //人力资源部
        Component hrDepart_BJ  = new Leaf();

        bj.add(sh);
        bj.add(hz);
        bj.add(financialDepart_BJ);
        bj.add(hrDepart_BJ);
        bj.display("北京");

    }
}

你可能会提出疑问:既然叶子节点不会再有子节点,为什么还要实现add和remove方法呢?这里涉及到两种模式:透明模式和安全模式


透明模式:


在Component中声明所有用来管理子对象的方法,其中包括add、remove等,这样实现Component接口的所有子类都具备了add和remove。这样的好处就是叶节点和枝节点对于外界没有区别。但问题也很明显,因为这些方法的实现,对于叶子节点来说,没有意义。


安全模式:


也就是在Component接口中不去声明add和remove方法,那么子类的Leaf中国也就不用去实现它,而在Compisite声明所有用来管理子类对象的方法,这样解决了问题,但是不过由于不透明,所以树叶和树枝将不具有相同的接口,客户端的调用需要做响应的判断,带来了不便。


如何选择,根据需求吧。

4. 何时使用组合模式


当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。


5. 组合模式的好处

  • 基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了
  • 用户不用关心到底是处理一个叶子节点还是一个组合组件,也就用不着为定义组合而写一些组合判断了,也就是说组合模式让客户可以一致地使用组合结构和单个对象。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值