组合模式

简介: 组合模式标签 : Java与设计模式 组合模式: 将对象组合成树形结构以表示‘部分-整体’的层次结构, 使得用户对单个对象和组合对象的使用具有一致性.

组合模式

标签 : Java与设计模式


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

  • 解析
    • 组合模式描述了如何将容器和叶子节点进行递归组合, 使用户在使用时可一致的对待容器和叶子, 为处理树形结构提供了完美的解决方案.
    • 当容器对象的指定方法被调用时, 将遍历整个树形结构, 并执行调用. 整个过程递归处理.

      (图片来源: 设计模式: 可复用面向对象软件的基础)

模式实现

案例: 杀毒软件


使对文件(Image/Text/Video/…)杀毒与对文件夹(Folder)的杀毒暴露统一接口.


Component

  • 组合模式中的对象声明接口, 在适当情况下, 实现所有类共有接口的默认行为.
  • 声明一个接口用于访问和管理Component子组件.
/**
 * @author jifang
 * @since 16/8/24 上午10:19.
 */
public abstract class AbstractFileComponent {

    protected String name;

    protected AbstractFileComponent(String name) {
        this.name = name;
    }

    protected void printDepth(int depth) {
        for (int i = 0; i < depth; ++i) {
            System.out.print('-');
        }
    }

    protected abstract void add(AbstractFileComponent component);

    protected abstract void remove(AbstractFileComponent component);

    protected abstract void killVirus(int depth);
}

Leaf

  • 叶子对象: 定义没有有分支节点的行为:
class ImageFileLeaf extends AbstractFileComponent {

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

    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("图片文件 [" + name + "]杀毒");
    }
}

class TextFileLeaf extends AbstractFileComponent {

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

    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("文本文件 [" + name + "]杀毒");
    }
}

class VideoFileLeaf extends AbstractFileComponent {

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

    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }

    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("视频文件 [" + name + "]杀毒");
    }
}

Composite

  • 容器对象: 定义有分支节点的行为, 用来存储子部件, 实现与子部件有关的操作:
public class FolderFileComposite extends AbstractFileComponent {

    private List<AbstractFileComponent> components = new LinkedList<>();

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

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

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

    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("目录 [" + name + "]杀毒");

        for (AbstractFileComponent component : components) {
            component.killVirus(depth + 2);
        }
    }
}
  • Client
public class Client {

    @Test
    public void client() {
        ImageFileLeaf image = new ImageFileLeaf("九寨沟.jpg");
        VideoFileLeaf video = new VideoFileLeaf("龙门飞甲.rmvb");
        TextFileLeaf text = new TextFileLeaf("解忧杂货店.txt");

        FolderFileComposite home = new FolderFileComposite("/home");
        home.add(image);
        home.add(video);
        home.add(text);

        FolderFileComposite root = new FolderFileComposite("/");
        root.add(home);
        root.add(new TextFileLeaf("/authorized_keys"));
        root.add(new FolderFileComposite("/etc"));

        root.killVirus(0);

    }
}

上面的实现方式是透明方式: 直接在Component中声明add()/remove(). 这样做的好处是叶节点和枝节点对于外界没有任何区别, 他们具有完全一致的行为接口. 但问题是对叶节点实现add()/remove()没有任何意义. 所以还有另一种实现方式安全方式, 也就是在Component中不去声明add()/remove(), 而是在Composite声明所有用来管理子类对象的方法, 不过由于不够透明, 所以叶节点与枝节点将不具有相同接口, 客户端调用需要作出相应判断, 带来了不便, 关于该问题的详细信息可参考: 组合模式(Composite)的安全模式与透明模式.


小结

  • 组合模式定义了基本对象组合对象的类层次结构, 基本对象可以被组合成更复杂的组合对象, 而这个组合对象又可以被组合, 这样不断地递归下去, 这样在客户代码中任何用到基本对象的地方都可以使用组合对象.
  • 用户不用关心到底是处理一个叶节点还是处理一个枝节点, 也用不着为定义组合而写一些选择判断语句.

总的来说: 组合模式让用户可以一致地使用组合结构单个对象.

  • 场景
    当需求中是体现部分整体层次的结构时, 以及希望用户可以忽略组合对象与单个对象的不同, 统一地使用组合中的所有对象时, 就应该考虑使用组合模式了:
    • 操作系统资源管理器
    • GUI容器视图
    • XML文件解析
    • OA系统中组织机构处理
    • Junit单元测试框架
      • TestCase(叶子)、TestUnite(容器)、Test接口(抽象)

参考
设计模式: 可复用面向对象软件的基础
大话设计模式
高淇讲设计模式
JAVA设计模式十七–Composite(组合模式)
设计模式系列-组合模式
组合模式(Composite)的安全模式与透明模式

目录
相关文章
|
存储 JSON Shell
Grafana 系列文章(三):Tempo- 使用 HTTP 推送 Spans
Grafana 系列文章(三):Tempo- 使用 HTTP 推送 Spans
Grafana 系列文章(三):Tempo- 使用 HTTP 推送 Spans
|
网络协议 网络性能优化 算法
iptables深入解析-mangle篇
      讲了filter、ct、nat 现在剩下最后一个知名模块mangle,但是自身虽然知道内核支持修改数据包的信息,它主要用在策略路由和qos上.我们就具体分析一下.      mangle表主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(T...
7968 0
|
人工智能 算法 芯片
《C++与 ASIC 芯片:人工智能领域的强力搭档》
在AI发展中,C++与ASIC芯片的协同应用成为关键探索方向。C++以其高性能和对底层硬件的精细控制,与ASIC芯片的高度优化计算能力相结合,共同推动AI系统在性能、能效上的突破,特别是在智能安防、自动驾驶等领域展现巨大潜力。
193 11
|
10月前
|
运维 监控 安全
代理IP故障排查,怎样快速锁定问题?
在信息化时代,互联网不可或缺,业务需求使HTTP动态代理IP的应用日益广泛。为快速排查代理IP故障,可采取以下步骤:1. 检查代理IP有效性(Ping测试、HTTP请求测试);2. 监控连接速度(延迟、带宽测试);3. 分析错误信息(HTTP状态码、错误日志);4. 检查代理设置(配置文件、协议支持);5. 使用调试工具(Wireshark、浏览器开发者工具);6. 咨询服务提供商;7. 检查网络环境(防火墙、ISP限制);8. 逐步故障排除并记录变化。通过这些方法,能有效找出并解决问题。
361 5
|
存储 Oracle 关系型数据库
|
编解码 算法 数据安全/隐私保护
基于BP译码的LDPC误码率matlab仿真,分析码长,码率,信道对译码性能的影响,对比卷积码,turbo码以及BCH码
本程序系统基于BP译码的LDPC误码率MATLAB仿真,分析不同码长、码率、信道对译码性能的影响,并与卷积码、Turbo码及BCH编译码进行对比。升级版增加了更多码长、码率和信道的测试,展示了LDPC码的优越性能。LDPC码由Gallager在1963年提出,具有低复杂度、可并行译码等优点,近年来成为信道编码研究的热点。程序在MATLAB 2022a上运行,仿真结果无水印。
279 0
|
机器学习/深度学习 人工智能 算法
认识AI,探索AI如何奇思妙想
AI的快速演进正在加速AGI的到来,不止步于工具的AI让我们意识到它也绝不仅仅意味着算法和代码。当我们真的把人工智能当作智能体的时候总要去思考“AI是什么”这一个问题。关于意识的理论模型各自提供了意识产生机制于AI的不同解释,目前尚无定论,但它们都在学术界激发了广泛的讨论与研究。也欢迎你在评论区聊聊你会怎么向别人介绍AI?你认为AI是如何奇思妙想的,它具有意识吗?
564 0
|
移动开发 人工智能 前端开发
介绍一些免费 的 html 5模版网站 和配色 网站
介绍一些免费 的 html 5模版网站 和配色 网站
3631 3
|
API C# Windows
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
768 0
|
存储 测试技术 Go
Golang 包:构建模块化代码的基石
【8月更文挑战第31天】
203 0