结构型模式-组合模式(树形结构的处理)(代码片段)

ading-blog ading-blog     2023-01-01     376

关键词:

目录

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

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

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设计模式-刘伟

优雅的处理树状结构——组合模式总结(代码片段)

1、前言本模式经 遍历“容器”的优雅方法——总结迭代器模式 引出,继续看最后的子菜单的案例2、组合模式的概念组合模式,也叫Composite模式……是构造型的设计模式之一。组合模式允许对象组合... 查看详情

组合模式(代码片段)

...对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来... 查看详情

组合模式结构模式(代码片段)

组合模式Compositeobjectsintotreestructurestorepresentpart-wholehierarchies.Compositeletsclientstreatindividualobjectsandcompositionsofobjectsuniformly.将对象组合成树形结构以表示"整体-部分"的层次结构,组合模式允许客户端统一处理单个对象或组合对象。@Slf... 查看详情

结构型模式——组合模式(代码片段)

...,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。2作用与意义l 意图:将对象组合成树形结构... 查看详情

组合模式(代码片段)

...端对单个对象和组合对象保持一致的方式处理类型:结构型适用场景:希望客户端可以忽略组合对象与单个对象的差异时处理一个树形结构时优点:清楚地定义分层次的负责对象,表示对象 查看详情

设计模式之组合模式(代码片段)

组合模式的基本介绍:又叫部分整体模式。创建了对象组的树形结构,将对象组合成树形结构以表示"整体-部分"的层次关系。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。组合模式使得用户对单个对象和组合... 查看详情

设计模式完结--组合模式---树形结构的处理

树形结构的处理——组合模式(一)组合模式为处理树形结构提供了一种较为完美的解决方案,它描述了如何将容器和叶子进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待 容器和叶子。所以:抽象类... 查看详情

设计模式之组合模式(代码片段)

组合模式1.简要概述2.模式结构3.实现代码4.优点好处5.缺点弊端6.应用场景7.应用示例1.简要概述组合模式又叫做部分整体模式,它将对象组合成树形结构来表示“整体与部分”之间的层次关系。组合模式使得用户对单个对象和... 查看详情

c#设计模式09——组合模式的写法(代码片段)

1.什么是C#组合模式?组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“整体/部分”层次结构。使用此模式,客户端可以按相同的方式处理单个对象和对象集合,而不必关注它们是单个对象还是组合对象。... 查看详情

设计模式--组合模式(代码片段)

组合模式定义:也称为整体-部分(Part-Whole)模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的   使用具有一致性。组合模式一般用来描述整... 查看详情

设计模式的征途—9.组合(composite)模式

...等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题。组合模式通过一种巧妙的设计方案来使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致地处理树形结构中的叶子节点(不... 查看详情

组合模式(代码片段)

模式动机  对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象,如子文件夹和文件)并调用执行。(递归调用)... 查看详情

结构型设计模式-组合模式(代码片段)

...0c;用来表示部分还是整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。二:透明组合模式案例需求:打印某个菜单下的所有菜单名字及菜单项的名字。MenuComponent&#x 查看详情

15组合模式(代码片段)

组合模式:组合模式(Composite),将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。组合模式UML结构图:组合模式的目的:让客户端不再区分操作的是组合对象... 查看详情

组合模式以及hashmap的设计分析(不包括具体实现)(代码片段)

组合模式1.基本介绍组合模式(CompositePattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系组合模式依据树形结构来组合对象,用来表示部分以及整体层次,属于结构... 查看详情

设计模式结构型组合模式(代码片段)

...0c;用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。1.2结构组合模式主要包含三种角色:抽象根节点():定义系统各层次对象的共有方法和属性,可以 查看详情

2018.4.20设计模式之组合模式(代码片段)

什么是组合模式?组合模式是指将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。有时候又叫做部分-整体模式,是用于把一组相似的对象当作一个单一的对象... 查看详情

设计模式@第12章:组合模式(代码片段)

...,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式。组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象组合模式原理类图对原 查看详情