最新文章 (全部类别)
.NETCore WebApi阻止接口重复调用(请求并发操作)
VS2022消除编译警告
“SymmetricAlgorithm.Create(string)”已过时:“Cryptographic factory methods accepting an algorithm name are obsolete. Use the parameterless Create factory method on the algorithm type instead
SHA256Managed/SHA512Managed已过时:Derived cryptographic types are obsolete. Use the Create method on the base type instead
MD5CryptoServiceProvider已过时:Derived cryptographic types are obsolete. Use the Create method on the base type instead
C#使用HttpClient获取IP地址位置和网络信息
判断IP是否是外网IP、内网IP
C#使用HttpClient获取公网IP
WebRequest.Create(string)已过时:WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead
C#根据第三方提供的IP查询服务获取公网外网IP地址
html/dom/js/javascript开发记录
调试ASP.NETCore Web站点 - 清理IISExpress缓存数据(js,css)
EFCore+Oracle根据不同的Schema连接数据库
主程序集成CSFramework.EF 数据库框架(.NET7版本)
CSFramework.EF数据库框架简介(.NET8+EFCore)
迁移ECS服务器:导致ORACLE监听服务启动不了解决方案
SQLite数据库
VS2022编译报错:Visual Studio 容器工具需要 Docker Desktop
.NET 9 预览版+C#13新功能
EFCore禁用实体跟踪
WebApi开发框架V3.0 (.NETCore+EFCore) 增加AppSettings全局参数类
C#获取应用程序所有依赖的程序集
LINQ Expression 多条件复合条件组合(And/Or)
CSFrameworkV6客户案例 - MHR - 宁德时代制造人力资源系统
CS软件授权注册系统V3 - 发布证书
C/S软件授权注册系统V3.0(Winform+WebApi+.NET8+EFCore版本)
CS软件授权注册系统V3 - 购买方式
CS软件授权注册系统V3 - 试用版下载
CS软件授权注册系统-客户登记(制作证书)
C/S软件授权注册系统V3.0 - 管理员工具
CSFrameworkV6旗舰版开发框架 - 集成软件授权认证系统
CSFramework.Authentication 软件证书管理系统 - 制作软件客户授权证书
CSFramework.Authentication 软件证书管理系统 - MAC地址管理
CSFramework.Authentication 软件授权证书管理系统
Login/Logout接口调用dalUser的Login/Logout方法
C# Newtonsoft.Json.Linq.JObject 转对象
CSFramework.Authentication 软件授权认证系统 - 软件测试报告
C/S架构软件开发平台 - 旗舰版V6.0 - 底层框架迭代开发
C/S架构软件开发平台 - 旗舰版V6.1新功能 - 增加软件授权认证模块
C/S架构软件开发平台 - 旗舰版CSFrameworkV6 Bug修改记录
CS软件授权注册系统V3 - 开发手册 - 软件集成与用户注册
CS软件授权注册系统-模拟MES/ERP用户注册软件
CS软件授权注册系统-发布/部署WebApi服务器(IIS+.NET8+ASP.NETCore)
CS软件授权注册系统-VS2022调试WebApi接口
.NETCore Console控制台程序使用ILogger日志
CS软件授权注册系统-WebApi服务器介绍
ASP.NETCore集成Swagger添加Authorize按钮Bearer授权
CS软件授权注册系统-WebApi服务器配置
.NETCore WebApi发布到IIS服务器无法打开swagger
.NET8/ .NETCore /ASP.NETCore 部署WebApi到IIS服务器需要安装的运行环境
.net敏捷开发,创造卓越

GoF设计模式:组合模式(Composite Pattern)—树形结构的处理


GoF设计模式:组合模式(Composite Pattern)—树形结构的处理

模式概述

树形结构在软件中随处可见,例如操作系统中的目录结构、应用软件中的菜单、办公系统中的公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题。组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致性地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点)。

模式定义

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

模式结构图

组合模式结构图如下所示:

组合模式(Composite Pattern)——树形结构的处理

在组合模式结构图中包含如下几个角色:

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。

  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。

  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

模式伪代码

对于客户端而言,一般针对抽象构件编程,而无须关心其具体子类是容器构件还是叶子构件。抽象构建类典型代码如下:

public abstract class Component {
    public abstract void add(Component c); //增加成员

    public abstract void remove(Component c); //删除成员

    public abstract Component getChild(int i); //获取成员

    public abstract void operation();  //业务方法
}

如果继承抽象构件的是叶子构件,则其典型代码如下所示:

public class Leaf extends Component {
    @Override
    public void add(Component c) {
        //异常处理或错误提示 
    }

    @Override
    public void remove(Component c) {
        //异常处理或错误提示 
    }

    @Override
    public Component getChild(int i) {
        //异常处理或错误提示 
        return null;
    }

    @Override
    public void operation() {
        //叶子构件具体业务方法的实现
    }
}

如果继承抽象构件的是容器构件,则其典型代码如下所示:

public class Composite extends Component {

    private List<Component> list = new ArrayList<>();

    @Override
    public void add(Component c) {
        list.add(c);
    }

    @Override
    public void remove(Component c) {
        list.remove(c);
    }

    @Override
    public Component getChild(int i) {
        return (Component) list.get(i);
    }

    @Override
    public void operation() {
        //容器构件具体业务方法的实现
        //递归调用成员构件的业务方法
        for (Object obj : list) {
            ((Component) obj).operation();
        }
    }
}

客户端对抽象构件类进行编程

public class Client {
    public static void main(String[] args) {
        Component component;
        component = new Leaf();
        //component = new Composite();

        // 无须知道到底是叶子还是容器
        // 可以对其进行统一处理
        component.operation();
    }
}

模式简化

透明组合模式

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

透明组合模式的完整结构图如下:

组合模式(Composite Pattern)——树形结构的处理

也可以将叶子构件的add()remove()等方法的实现代码移至Component中,由Component提供统一的默认实现,这样子类就不必强制去实现管理子Component。代码如下所示:

public abstract class Component {
    public void add(Component c) {
        throw new RuntimeException("不支持的操作");
    }

    public void remove(Component c) {
        throw new RuntimeException("不支持的操作");
    }

    public Component getChild(int i) {
        throw new RuntimeException("不支持的操作");
    }

    public abstract void operation();  //业务方法
}

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

安全组合模式

安全组合模式中,在抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。

安全组合模式的完整结构图如下:

组合模式(Composite Pattern)——树形结构的处理

此时Component就应该这样定义了

public abstract class Component {
    // 业务方法
    public abstract void operation();
}

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

模式应用

模式在JDK中的应用

Java SE中的AWTSwing包的设计就基于组合模式,在这些界面包中为用户提供了大量的容器构件(如Container)和成员构件(如CheckboxButtonTextComponent等),其结构如下图所示

组合模式(Composite Pattern)——树形结构的处理

Component类是抽象构件,CheckboxButtonTextComponent是叶子构件,而Container是容器构件,在AWT中包含的叶子构件还有很多。在一个容器构件中可以包含叶子构件,也可以继续包含容器构件,这些叶子构件和容器构件一起组成了复杂的GUI界面。除此以外,在XML解析组织结构树处理文件系统设计等领域,组合模式都得到了广泛应用。

模式在开源项目中的应用

Springorg.springframework.web.method.support.HandlerMethodArgumentResolver使用了安全组合模式。提取关键代码如下:

public interface HandlerMethodArgumentResolver {
    
    boolean supportsParameter(MethodParameter parameter);

    Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
                           NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

再看下它的一个实现类org.springframework.web.method.support.HandlerMethodArgumentResolverComposite

public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {


    private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<>();

    /**
     * Add the given {@link HandlerMethodArgumentResolver}.
     */
    public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver resolver) {
        this.argumentResolvers.add(resolver);
        return this;
    }

    /**
     * Add the given {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
     */
    public HandlerMethodArgumentResolverComposite addResolvers(
            @Nullable HandlerMethodArgumentResolver... resolvers) {

        if (resolvers != null) {
            Collections.addAll(this.argumentResolvers, resolvers);
        }
        return this;
    }

    /**
     * Clear the list of configured resolvers.
     */
    public void clear() {
        this.argumentResolvers.clear();
    }


    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return getArgumentResolver(parameter) != null;
    }


    @Override
    public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

        HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
        if (resolver == null) {
            throw new IllegalArgumentException("Unsupported parameter type [" +
                    parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
        }
        return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
    }
}

模式总结

主要优点

  1. 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。

  2. 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。

  3. 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

适用场景

(1) 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。

(2) 在一个使用面向对象语言开发的系统中需要处理一个树形结构。

(3) 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
C/S框架网
上一篇:GoF设计模式:外观模式(Facade Pattern)—提供统一的入口
下一篇:GoF设计模式:工厂模式(Factory Pattern)
评论列表

发表评论

评论内容
昵称:
关联文章

GoF设计模式组合模式(Composite Pattern)—树形结构处理
GoF设计模式:职责链模式(Chain of Responsibility Pattern)—请求链式处理
GoF设计模式:工厂模式(Factory Pattern)
GoF设计模式:桥接模式(Bridge Pattern)—处理多维度变化
GoF设计模式:适配器模式(Adapter Pattern)—不兼容结构协调
GoF设计模式:装饰模式(Decorator Pattern)—扩展系统功能
GoF设计模式:访问者模式(Visitor Pattern)—操作复杂对象结构
GoF设计模式:原型模式(Prototype Pattern)—对象克隆
GoF设计模式:享元模式(Flyweight Pattern)—实现对象复用
GoF设计模式:代理模式(Proxy Pattern)—对象间接访问
GoF设计模式:单例模式(Singleton Pattern)—确保对象唯一性
GoF设计模式:外观模式(Facade Pattern)—提供统一入口
GoF设计模式:中介者模式(Mediator Pattern)—协调多个对象之间交互
GoF设计模式:迭代器模式(Iterator Pattern)—遍历聚合对象中元素
GoF设计模式:命令模式(Command Pattern)—请求发送者与接收者解耦
GoF设计模式:建造者模式(Builder Pattern)—复杂对象组装与创建
开发应用 - 策略模式(Strategy Pattern) 常用设计模式
C#设计模式应用-单件模式(Singleton Pattern)
设计模式 - 外观模式应用(Façade Pattern)
开发应用-职责链模式(Chain Of Resposibility Pattern)

热门标签
软件著作权登记证书 .NET .NET Reactor .NET5 .NET6 .NET7 .NET8 .NET9 .NETFramework APP AspNetCore AuthV3 Auth-软件授权注册系统 Axios B/S B/S开发框架 B/S框架 BSFramework Bug Bug记录 C#加密解密 C#源码 C/S CHATGPT CMS系统 CodeGenerator CSFramework.DB CSFramework.EF CSFramework.License CSFrameworkV1学习版 CSFrameworkV2标准版 CSFrameworkV3高级版 CSFrameworkV4企业版 CSFrameworkV5旗舰版 CSFrameworkV6.0 CSFrameworkV6.1 CSFrameworkV6旗舰版 DAL数据访问层 Database datalock DbFramework Demo教学 Demo实例 Demo下载 DevExpress教程 Docker Desktop DOM ECS服务器 EFCore EF框架 Element-UI EntityFramework ERP ES6 Excel FastReport GIT HR IDatabase IIS JavaScript LINQ MES MiniFramework MIS MySql NavBarControl NETCore Node.JS NPM OMS Oracle资料 ORM PaaS POS Promise API PSD RedGet Redis RSA SAP Schema SEO SEO文章 SQL SQLConnector SQLite SqlServer Swagger TMS系统 Token令牌 VS2022 VSCode VS升级 VUE WCF WebApi WebApi NETCore WebApi框架 WEB开发框架 Windows服务 Winform 开发框架 Winform 开发平台 WinFramework Workflow工作流 Workflow流程引擎 XtraReport 安装环境 版本区别 报表 备份还原 踩坑日记 操作手册 达梦数据库 代码生成器 迭代开发记录 功能介绍 国际化 基础资料窗体 架构设计 角色权限 开发sce 开发工具 开发技巧 开发教程 开发框架 开发平台 开发指南 客户案例 快速搭站系统 快速开发平台 框架升级 毛衫行业ERP 秘钥 密钥 权限设计 软件报价 软件测试报告 软件加壳 软件简介 软件开发框架 软件开发平台 软件开发文档 软件授权 软件授权注册系统 软件体系架构 软件下载 软件著作权登记证书 软著证书 三层架构 设计模式 生成代码 实用小技巧 视频下载 收钱音箱 数据锁 数据同步 微信小程序 未解决问题 文档下载 喜鹊ERP 喜鹊软件 系统对接 详细设计说明书 新功能 信创 行政区域数据库 需求分析 疑难杂症 蝇量级框架 蝇量框架 用户管理 用户开发手册 用户控件 在线支付 纸箱ERP 智能语音收款机 自定义窗体 自定义组件 自动升级程序
联系我们
联系电话:13923396219(微信同号)
电子邮箱:23404761@qq.com
站长微信二维码
微信二维码