结构型模式 - 组合模式

系列文章目录

设计模式 - 设计原则

创建型模式 - 单例模式(一)
创建型模式 - 工厂模式(二)
创建型模式 - 原型模式(三)
创建型模式 - 建造者模式(四)

结构型模式 - 适配器模式(一)
结构型模式 - 桥接模式(二)
结构型模式 - 装饰器模式(三)
结构型模式 - 组合模式(四)
结构型模式 - 外观模式(五)
结构型模式 - 享元模式(六)
结构型模式 - 代理模式(七)

行为型模式 - 模板方法模式(一)
行为型模式 - 命令模式(二)
行为型模式 - 访问者模式(三)
行为型模式 - 迭代器模式(四)
行为型模式 - 观察者模式(五)
行为型模式 - 中介者模式(六)
行为型模式 - 备忘录模式(七)
行为型模式 - 解释器模式(八)
行为型模式 - 状态模式(九)
行为型模式 - 策略模式(十)
行为型模式 - 责任链模式(十一)



前言

代码地址


一、组合模式

1.1 组合模式介绍

  • 组合(Composite)模式:

又叫整体-部分(Part-Whole)模式,它是一种讲对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系;

  • 组合模式依据树形结构来组合对象,用来表示部分以及整体层次;
  • 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象

1.2 组合模式结构

在这里插入图片描述

  • 抽象构件(Component)角色:
  • 主要作用是为树叶构件(Leaf)和树枝(Composite)声明公共接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理Component 子部件,可以是抽象类或接口;
  • 树叶构件(Leaf)角色:
  • 是组合中的叶节点对象,他没有子节点,用于继承或实现抽象构件;
  • 树枝构件(Composite)角色/中间构件:
  • 是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件,它只要作用就是存储和管理子部件,通常包含添加、删除、获取子节点等方法

二、实现

例子:

  • 实现一个树状图;

2.1 组合模式实现

在这里插入图片描述

package com.dozezz.designpattern.composite.composite;

/**
 * @Description:
 * @Author: dozezz
 * @Date: 2021/7/19 20:25
 * @Version: 1.0
 */
public abstract class Component {
    private String name;
    private String desc;

    public Component() {
    }

    public Component(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
//    为啥不写成抽象的,因为子类未必都需要这方法,如果设计成抽象,每个子类都必须实现它;
//    protected abstract void add();

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

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

//    这方法子类都需要实现(例子)
    protected abstract void print();

    public String getName() {
        return name;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public String toString() {
        return "Component{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
package com.dozezz.designpattern.composite.composite;

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

/**
 * @Description:
 * @Author: dozezz
 * @Date: 2021/7/19 20:35
 * @Version: 1.0
 */
public class CompositeNode extends Component{

    List<Component> components = new ArrayList<>();

    public CompositeNode() {
    }

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

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

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

    @Override
    protected void print() {
        System.out.println(getName());
    }
}
package com.dozezz.designpattern.composite.composite;

/**
 * @Description: 叶子结点
 * @Author: dozezz
 * @Date: 2021/7/19 20:34
 * @Version: 1.0
 */
public class LeafNode extends Component{

    public LeafNode(String name, String desc) {
        super(name, desc);
    }

    @Override
    protected void print() {
        System.out.println(getName());
    }
}
package com.dozezz.designpattern.composite.composite;


/**
 * @Description:测试
 * @Author: dozezz
 * @Date: 2021/7/19 20:06
 * @Version: 1.0
 */
public class ClientTest {

    static void tree(Component component,int deepth){
        for (int i = 0; i < deepth; i++) {
            System.out.print("----");
        }
        component.print();

        if(component instanceof CompositeNode){
            for (Component compositeNode: ((CompositeNode)component).components){
                tree(compositeNode,deepth + 1);
            }
        }
    }

    public static void main(String[] args) {
        Component component = new CompositeNode("root", "root");
        Component component1 = new CompositeNode("c1", "c1");
        Component component2 = new CompositeNode("c2", "c2");
        LeafNode leafNode = new LeafNode("c11", "c11");
        LeafNode leafNode1 = new LeafNode("c12", "c12");
        Component component3 = new CompositeNode("c21", "c21");
        LeafNode leafNode2 = new LeafNode("c211", "c211");
        LeafNode leafNode3 = new LeafNode("c212", "c212");
        component.add(component1);
        component.add(component2);
        component1.add(leafNode);
        component1.add(leafNode1);
        component2.add(component3);
        component3.add(leafNode2);
        component3.add(leafNode3);

        tree(component,0);

//        root
//        ----c1
//        --------c11
//        --------c12
//        ----c2
//        --------c21
//        ------------c211
//        ------------c212
    }
}

三、组合模式

3.1 组合模式应用场景

  • 在需要表示一个对象整体与部分的层次结构的场合;
  • 要求对隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合;

3.2 组合模式优缺点

  • 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无需关系自己处理的是单个对象还是组合对象,简化了客户端代码;
  • 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码;
  • 设计比较复杂,客户端需要花费更多时间理清类之间的层次关系;
  • 不容易限制容器中的组件,不容易用继承的方法来增加构件的功能;

四、参考文献

  • http://c.biancheng.net/view/1373.html
  • https://www.bilibili.com/video/BV1G4411c7N4?p=54&spm_id_from=pageDriver
  • https://baiyp.ren/JAVA%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-04%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值