Java设计模式之组合模式

组合模式

Composite

定义: 将对象组合成树形结构来表示"部分–整体"的层次结构

组合模式使得单个对象和组合对象的使用具有一致性

角色

角色图(大话设计模式图)

在这里插入图片描述

  • Component: 抽象类或接口 用来访问和管理它的子部件:LeafComposite
  • Composite: Component的子部件,拥有子节点,要实现与子部件相关方法
  • Leaf: Component的子部件,没有子节点 (所以不用实现与子部件相关方法)

公司例子

组合模式把多个对象组合成树型结构

公司中有分公司或部门,公司或分公司就是Composite,因为它们一定有子节点,而部门就是Leaf,部门下面没有管理的部件了,所以部门是叶子节点

Composite: 公司,子公司

Leaf: 部门

在这里插入图片描述

例子代码

  • 透明方式: Leaf也实现Component中与子部件相关方法,但这么做无意义

  • 安全方式: 代码中Leaf未重写的使用了Component中的add,remove(抛出异常)

    这么写当Leaf调用add,remove时会抛出异常,安全

代码结构图

在这里插入图片描述

Component

/**
 * @author Tc.l
 * @Date 2021/1/29
 * @Description:公司接口
 */
public abstract class Component {
    private String name;

    protected String getName() {
        return name;
    }

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

    protected void setName(String name) {
        this.name = name;
    }

    public void add(Component component){
        throw new UnsupportedOperationException();
    }

    public void remove(Component component){
        throw new UnsupportedOperationException();
    }

    public abstract void printName();
}

Composite

/**
 * @author Tc.l
 * @Date 2021/1/29
 * @Description:CompositeA(总公司)
 */
public class CompositeA extends Component{
    //列表中装的是分公司或部门
    private List<Component> components;

    public CompositeA(String name) {
        super(name);
        components = new ArrayList<Component>();
    }

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

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

    @Override
    public void printName() {
        System.out.println(getName());
        System.out.println("=======================");
        for (Component component : components) {
            component.printName();
        }
        System.out.println("=======================");
    }
}
/**
 * @author Tc.l
 * @Date 2021/1/29
 * @Description:CompositeB(分公司)
 */
public class CompositeB extends Component{
    //列表中装的是部门
    private List<Component> components;

    public CompositeB(String name) {
        super(name);
        components = new ArrayList<Component>();
    }

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

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

    @Override
    public void printName() {
        System.out.println(getName());
        System.out.println("-----------------------------");
        for (Component component : components) {
            component.printName();
        }
        System.out.println("-----------------------------");

    }
}

Leaf

/**
 * @author Tc.l
 * @Date 2021/1/29
 * @Description:Leaf(部门)
 */
public class Leaf extends Component{
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void printName() {
        System.out.println(getName());
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //总公司
        CompositeA head = new CompositeA("太菜了中国总公司");

        //分公司
        CompositeB jiangxiBranch = new CompositeB("太菜了江西分公司");
        CompositeB guangdongBranch = new CompositeB("太菜了广东分公司");

        //部门
        Leaf finance = new Leaf("财务部");
        Leaf technology = new Leaf("技术部");

        head.add(jiangxiBranch);
        head.add(guangdongBranch);
        head.add(finance);
        head.add(technology);

        jiangxiBranch.add(finance);
        guangdongBranch.add(technology);
        head.printName();
    }
}
/*
太菜了中国总公司
=======================
太菜了江西分公司
-----------------------------
财务部
-----------------------------
太菜了广东分公司
-----------------------------
技术部
-----------------------------
财务部
技术部
=======================
*/

排版不太好看还是画图出来明显

在这里插入图片描述

JDK中的组合模式

常用的HashMap就使用了组合模式

在这里插入图片描述

只不过它的Component抽象层有2层,一层接口一层抽象类

HashMap(Composite)聚合了子部件Node(Leaf) Node是HashMap的静态内部类

而在Component中抽象的put,remove方法,在HashMap(Composite)中进行重写,而在Node(Leaf)中未实现

因为Node是Leaf,没有子部件,实现put,remove无意义

Node实现Entry接口,Entry接口是Map的内部接口

static class Node<K,V> implements Map.Entry<K,V>

AbstractMap中的put方法也是安全方式

public V put(K key, V value) {
    throw new UnsupportedOperationException();
}

总结

特点

组合模式中定义了单个对象和组合对象这样的层次结构

单个对象:Leaf角色, 无子部件 (部门)

组合对象:composite角色 (分公司->部门) 还可以组合递归下去(总公司->分公司->部门)

一致性: 使用组合模式时不用关心到底是处理单个对象还是处理组合对象

使用场景

  1. 处理递归,分层的结构系统
  2. 需要体现 部分–整体结构
  3. 可以忽略单个对象和组合对象不同,统一使用组合中的对象时
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值