结构型模式-组合模式(树形结构的处理)

目录

  • 1. 定义
  • 2. 结构
  • 3. 代码实现
  • 4. 透明组合模式与安全组合模式
    • 4.1 透明组合模式
    • 4.1 安全组合模式
  • 5. 优缺点
  • 6. 适用场景
  • 7. 个人理解
  • 参考

树形结构在软件中随处可见,例如操作系统中的目录结构、应用软件中的菜单、办公系统中的公司组织结构等。

组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致性地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点)。

1. 定义

组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。

2. 结构

在组合模式中引入了抽象构件类Component,它是所有容器类和叶子类的公共父类,客户端针对Component进行编程。组合模式结构如图所示:

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

3. 代码实现

代码实现了一个公司的组织架构,包括各级公司,各级公司包括各部门,AbstractOrganization充当抽象构建类,Company充当容器构建类(可以定义其他容器构建类),Department充当叶子构建类(可以定义其他叶子构建类)。

AbstractOrganization

public abstract class AbstractOrganization {

    public abstract void add(AbstractOrganization organization);

    public abstract void remove(AbstractOrganization organization);

    public abstract  AbstractOrganization getChild(int i);

    public abstract void notifyMessage();

}

Company

public class Company extends AbstractOrganization {

    private List<AbstractOrganization> organizationList=new ArrayList<>();
    private String name;

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

    @Override
    public void add(AbstractOrganization organization) {
        organizationList.add(organization);
    }

    @Override
    public void remove(AbstractOrganization organization) {
        organization.remove(organization);
    }

    @Override
    public AbstractOrganization getChild(int i) {
        return organizationList.get(i);
    }

    @Override
    public void notifyMessage() {
        System.out.println("对公司:"+name+" 进行通知");
        for (AbstractOrganization organization:organizationList){
            organization.notifyMessage();
        }
    }
}

Department

public class Department extends AbstractOrganization {

    private String name;

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

    @Override
    public void add(AbstractOrganization organization) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void remove(AbstractOrganization organization) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public AbstractOrganization getChild(int i) {
        System.out.println("对不起,不支持该方法!");
        return null;
    }

    @Override
    public void notifyMessage() {
        System.out.println("对"+name+" 进行通知");
    }
}

Client

public class Client {

    public static void main(String[] args) {
        AbstractOrganization c1,c2,d1,d2,d3;
        c1=new Company("总公司");
        c2=new Company("分公司1");
        d1=new Department("总公司部门1");
        d2=new Department("分公司部门1");
        d3=new Department("分公司部门2");
        c1.add(c2);
        c1.add(d1);
        c2.add(d2);
        c2.add(d3);
        //客户端无序关心节点的层次结构,对节点可以进行统一处理
        c1.notifyMessage();
        System.out.println("-------------");
        c2.notifyMessage();
    }
}

//对公司:总公司 进行通知
//对公司:分公司1 进行通知
//对分公司部门1 进行通知
//对分公司部门2 进行通知
//对总公司部门1 进行通知
//-------------
//对公司:分公司1 进行通知
//对分公司部门1 进行通知
//对分公司部门2 进行通知

4. 透明组合模式与安全组合模式

4.1 透明组合模式

透明组合模式中,抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()以及getChild()等方法,这样做的好处是确保所有的构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以相同地对待所有的对象。

透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的。叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供add()、remove()以及getChild()等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)。

4.1 安全组合模式

Java AWT中使用的组合模式就是安全组合模式。

安全组合模式中,在抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。这种做法是安全的,因为根本不向叶子对象提供这些管理成员对象的方法,对于叶子对象,客户端不可能调用到这些方法。

安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。

客户端需要指定具体的容器类型,才能调用管理成员对象的方法。

Comapany c1,c2;
AbstractOrganization d1,d2,d3;
...
c1.notifyMessage();

5. 优缺点

  • 优点
  1. 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  2. 客户端可以一致地使用一个组合结构或其中单个对象,简化客户端代码。
  3. 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
  4. 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
  • 缺点
  1. 在增加新构件时很难对容器中的构件类型进行限制。因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。

6. 适用场景

  1. 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
  2. 在一个使用面向对象语言开发的系统中需要处理一个树形结构
  3. 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

7. 个人理解

组合模式用户处理类似树形结构的包含容器对象和叶子对象的层次结构,通过该模式可忽略整体与部分的差异,让客户端统一对待它们,同时符合“开闭原则”利于扩展。

参考

  1. Java设计模式-刘伟

原文地址:https://www.cnblogs.com/ading-blog/p/9678293.html

时间: 2024-10-12 03:42:18

结构型模式-组合模式(树形结构的处理)的相关文章

设计模式(结构型)之组合模式(Composite Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之桥接模式(Bridge Pattern)> http://blog.csdn.net/yanbober/article/details/45366781 概述 组合模式又叫做部分-整体模式,使我们在树型结构的问题中模糊简单元素和复杂元素的概念,客户程序可以像

结构型模式-组合模式

1.定义 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.介绍 组合模式属于结构型模式. 组合模式有时叫做部分-整体模式,主要是描述部分与整体的关系. 组合模式实际上就是个树形结构,一棵树的节点如果没有分支,就是叶子节点;如果存在分支,则是树枝节点. 我们平时遇到的最典型的组合结构就是文件和文件夹了,具体的文件就是叶子节点,而文件夹下还可以存在文件和文件夹,所以文件夹一般是树枝节点. 3.UML类图 角色说明: Component

9 结构型模式-----组合模式

模式动机(Composite Pattern):将对象组合成树形结构来表示“整体-部分”层次.操作时,使得对部分的操作与对整体的操作具有一致性. 模式结构图: 典型的Composite结构为: 模式代码: bt_组合模式.h: 1 #ifndef CP_H 2 #define CP_H 3 #include <iostream> 4 #include <vector> 5 using namespace std; 6 7 /* 8 抽象部件类 9 */ 10 class Compo

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

Composite模式也叫组合模式,是构造型的设计模式之一.通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树. Component (树形结构的节点抽象) - 为所有的对象定义统一的接口(公共属性,行为等的定义) - 提供管理子节点对象的接口方法 - [可选]提供管理父节点对象的接口方法  Leaf (树形结构的叶节点) Component的实现子类  Composite(树形结构的枝节点) Component的实现子类 适用于: 单个对象和组合对象的使用具有一致性.将对象组

java设计模式--结构型模式--组合模式

什么是组合模式,这个有待研究,个人觉得是各类组合而形成的一种结构吧. 组合模式: 1 组合模式 2 概述 3 将对象组合成树形结构以表示"部分-整体"的层次结构."Composite使得用户对单个对象和组合对象的使用具有一致性." 4 5 6 适用性 7 1.你想表示对象的部分-整体层次结构. 8 9 2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象. 10 11 12 参与者 13 1.Component 14 为组合中的对象声明接

Composite模式 组合模式

Android的ViewGroup 和 View 的关系,即是采用组合模式 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 我们可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象.我们可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象.客户端代码必须区别对象简单对象和容器对象,而实际上大多数情况下用户认为它们是一样的.对这些类区别使用,使得程序更加复杂.递归使用

设计模式--结构型模式--组合模式

1.组合模式 拿剪发办卡的事情来分析一下吧. 首先,一张卡可以在总部,分店,加盟店使用,那么总部可以刷卡,分店也可以刷卡,加盟店也可以刷卡,这个属性结构的店面层级关系就明确啦. 那么,总店刷卡消费与分店刷卡消费是一样的道理,那么总店与分店对会员卡的使用也具有一致性. 例子 那么加盟店就相当于叶子节点,分店和总店属于分支节点. 那我们的目的是什么呢?就是当我们在总店刷卡的时候,所有的下属店面都有了你的刷卡积分信息.因此,我们需要对具有层级关系的总店,分店,加盟店进行一致的处理,在刷卡的时候不需要关

第10章 结构型模式—组合模式

1. 组合模式(Composite Pattern)的定义 (1)将对象组合成树型结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. (2)组合模式的结构和说明 ①Component:抽象的组件对象,为组合中的对象声明接口,让客户端可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的功能提供缺省的实现. ②Leaf:叶子节点对象,定义和实现叶子对象的行为,不再包含其他子节点对象. ③Composite:组合对象,通常会存储子组件,定义包含子组件的那

设计模式(结构型)之外观模式(Facade Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之装饰者模式(Decorator Pattern)>http://blog.csdn.net/yanbober/article/details/45395747 概述 一个客户类需要和多个业务类交互,而这些业务类经常会作为整体出现,由于涉及到的类比较多,导致使