11.组合模式

场景

  1. 客户订单的目的地问题

    • 每个地方行政区划有三级至五级不等

    • 组织这个一样目录,供客户选择

    • 如果每级区划使用一个类,需要五个类,太复杂

在这里插入图片描述

  1. 于是我们可以把一组相似的对象当作一个单一的对象,为的是减少数据类型。

在这里插入图片描述

组合模式

定义

将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。

结构

  • 抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。

  • 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。

  • 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

UML类图

在这里插入图片描述

代码实现

实现

抽象构件

/**
 * 抽象构件
 */
public abstract class ComponentNode {
    private String name;

	 public String getName() {
        return name;
    }

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

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

    public abstract List<ComponentNode> getChildren();

    public abstract void add(ComponentNode node);

    public abstract void remove(ComponentNode node);
}

树叶构件

public class LeafNode extends ComponentNode{
    public LeafNode(String name) {
        super(name);
    }

    @Override
    public List<ComponentNode> getChildren() {
        return null;
    }

    @Override
    public void add(ComponentNode node) { }

    @Override
    public void remove(ComponentNode node) { }
}

树枝构件

public class CompositeNode extends ComponentNode {
    private List<ComponentNode> children = new ArrayList<>();

    public CompositeNode(String name) {
        super(name);
    }

    @Override
    public List<ComponentNode> getChildren() {
        return children;
    }

    @Override
    public void add(ComponentNode node) {
        children.add(node);
    }

    @Override
    public void remove(ComponentNode node) {
        children.remove(node);
    }
}

客户端调用

public class TestClient {

    public static void main(String[] args) {

        //根目录
        ComponentNode root = new CompositeNode("目的地");
        //第一级
        ComponentNode bj = new CompositeNode("北京");
        ComponentNode sh = new CompositeNode("上海");
        ComponentNode tj = new CompositeNode("天津");
        root.add(bj);
        root.add(sh);
        root.add(tj);
        //第二级,属于北京
        ComponentNode cyq = new CompositeNode("朝阳区");
        ComponentNode hdq = new CompositeNode("海淀区");
        ComponentNode xcq = new CompositeNode("西城区");
        bj.add(cyq);
        bj.add(hdq);
        bj.add(xcq);
        //第三级,属于朝阳区
        ComponentNode cwjd = new CompositeNode("朝外街道");
        ComponentNode slt = new CompositeNode("三里屯");
        cyq.add(cwjd);
        cyq.add(slt);
        //最后一级,没有子节点
        LeafNode leafNode = new LeafNode("三里屯卤煮店");
        slt.add(leafNode);
        System.out.println(JSON.toJSON(root));
    }
}

结果

{"children":[{"children":[{"children":[{"children":[],"name":"朝外街道"},{"children":[{"name":"三里屯卤煮店"}],"name":"三里屯"}],"name":"朝阳区"},{"children":[],"name":"海淀区"},{"children":[],"name":"西城区"}],"name":"北京"},{"children":[],"name":"上海"},{"children":[],"name":"天津"}],"name":"目的地"}

在这里插入图片描述

优缺点

优点

  • 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码
  • 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”

缺点

  • 设计较复杂,客户端需要花更多时间理清类之间的层次关系
  • 不容易限制容器中的构件
  • 不容易用继承的方法来增加构件的新功能

组合模式的本质

组合模式的本质:统一叶子对象和组合对象

组合模式通过吧叶子对象当成特殊的组合对象看待,叶子对象和组合对象全部当成Component对象,统一了叶子对象和组合对象

使用场景

  • 在需要表示一个对象整体与部分的层次结构的场合。
  • 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪了个王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值