当前位置: 首页 > article >正文

链式设计及设计模式的应用

链式设计

  1. 定义和概念

    • 链式设计模式是一种行为设计模式,它允许在对象上以链式调用的方式执行多个操作。在这种模式中,对象的方法返回对象本身(this),这样就可以在一个语句中连续调用多个方法,形成类似链条的调用方式。这种模式使得代码更加简洁、可读,并且在构建复杂对象或者执行一系列相关操作时非常有用。例如,在构建SQL查询语句或者配置对象时,链式设计模式可以很好地发挥作用。
  2. 结构和组成部分

    class ChainObject {
        constructor() {
            this.value = 0;
        }
        add(num) {
            this.value += num;
            return this;
        }
        multiply(num) {
            this.value *= num;
            return this;
        }
    }
    
    • 对象自身方法返回值:核心特点是对象的方法返回对象本身(this)。例如,在一个简单的链式调用的JavaScript对象中,代码可能如下:
    • 这里的addmultiply方法在执行操作后都返回this,使得可以连续调用这些方法,如new ChainObject().add(2).multiply(3)
    • 链式调用顺序:方法的调用顺序决定了操作的执行顺序。继续上面的例子,先调用add方法将value增加2,然后调用multiply方法将value乘以3。
  3. 优点

    • 代码简洁性:链式调用使得代码更加紧凑和简洁。相比于传统的多次调用对象方法并使用中间变量来保存结果的方式,链式设计模式可以在一行代码中完成多个操作。
      • 例如,在设置HTML元素的样式时,如果使用链式设计模式的JavaScript库(如jQuery的部分功能),可以这样写:$('div').css('color','red').css('font - size','16px');,而不是多次调用css方法并分别保存中间结果。
    • 可读性:当操作具有一定的逻辑顺序时,链式调用可以清晰地展示操作的流程。
      • 以构建一个复杂的URL为例,通过链式设计模式可以这样写:new URLBuilder().setProtocol('https').setDomain('example.com').setPath('/api/data');,从左到右可以很直观地理解是在依次设置URL的协议、域名和路径。
    • 配置的灵活性:在配置对象或者系统参数时,链式设计模式提供了很高的灵活性。可以根据需要选择调用哪些方法来配置对象,而不必一次性传入所有参数。
  4. 缺点

    • 调试复杂性:由于链式调用将多个操作连接在一起,在调试时可能会比较复杂。如果在链式调用中的某个方法出现问题,很难直接定位是哪个具体的调用导致的。
    • 方法链过长可能导致可读性下降:虽然链式设计模式在一定程度上可以提高可读性,但如果方法链过长,代码可能会变得难以理解。
    • 错误处理的复杂性:在链式调用中,如果一个方法出现错误,后续的方法可能无法正常执行,并且很难进行统一的错误处理。
  5. 应用场景

    • 数据库查询构建:在数据库访问层,链式设计模式可以用于构建复杂的查询语句。例如,在一个ORM(对象关系映射)框架中,可以这样构建一个查询:query.select('*').from('users').where('age > ', 18).orderBy('name');,通过链式调用依次选择列、指定表、设置筛选条件和排序规则。
    • 对象配置和初始化:用于配置复杂的对象,如在初始化一个图形绘制对象时,可以这样写:new Graphics().setColor('red').setShape('circle').setSize(100);,方便地设置图形的颜色、形状和大小等参数。
    • DOM操作(在前端开发中):在前端开发中,对HTML元素进行一系列操作时可以使用链式设计模式。例如,使用JavaScript库来操作DOM元素,像document.querySelector('div').style.color ='red'; document.querySelector('div').style.font - size = '16px';可以转换为链式调用document.querySelector('div').setStyle('color','red').setStyle('font - size','16px');(假设存在这样的setStyle方法且返回this),使得操作更加简洁和可读。

设计模式对链式设计应用

建造者模式(Builder Pattern)的变种

- **原理**:传统的建造者模式是将一个复杂对象的构建过程和它的表示分离,使得同样的构建过程可以创建不同的表示。在一些变种中,会采用链式调用的方式来设置对象的各个属性。
    * 例如,在构建一个复杂的汽车对象时,可能有品牌、颜色、配置等多个属性需要设置,通过链式调用可以这样构建:`CarBuilder builder = new CarBuilder(); Car car = builder.setBrand("Toyota").setColor("Blue").setConfiguration("High - end").build();`。这里的`CarBuilder`类中的`setBrand`、`setColor`等方法返回`this`(即`CarBuilder`对象本身),从而实现链式调用,最后通过`build`方法来生成最终的汽车对象。
- **优点**:这种链式调用方式使得对象的构建过程更加灵活和可读。用户可以根据自己的需求选择性地设置对象的属性,而且代码的顺序性能够清晰地展示对象构建的流程,就像在配置一个产品一样,一步一步地完成复杂对象的定制。

责任链模式(Chain of Responsibility Pattern)

- **原理**:责任链模式是为了处理请求而创建的多个对象组成的链,每个对象都有机会处理请求。在一些实现中,会采用链式设计来构建这个责任链。
    * 例如,在一个审批系统中,有多个审批环节(如部门主管审批、经理审批、总经理审批),可以通过链式调用将这些审批环节连接起来。每个审批环节对象有一个`setNextHandler`方法,该方法返回自身(`this`),用于连接下一个审批环节,如:
DepartmentHeadApproval departmentHead = new DepartmentHeadApproval();
ManagerApproval manager = new ManagerApproval(); 
departmentHead.setNextHandler(manager).processRequest(request);
    * 这里通过链式调用构建了一个审批链,当一个请求进来时,它会按照链的顺序依次经过各个审批环节,直到有一个环节处理完这个请求或者所有环节都无法处理。
- **优点**:这种链式设计使得责任链的构建更加灵活和直观。可以很方便地添加、删除或者重新排列责任链中的环节,而且在代码中能够清晰地看到各个环节之间的连接关系和顺序。

装饰器模式(Decorator Pattern)的链式装饰实现

- **原理**:装饰器模式是动态地给一个对象添加一些额外的职责。在链式设计的装饰器模式中,装饰器类的方法返回自身(`this`),这样就可以通过链式调用不断地给对象添加装饰。
    * 例如,在一个咖啡点单系统中,咖啡是基础对象,有牛奶、糖、奶油等装饰选项。可以这样实现链式装饰:`Coffee coffee = new SimpleCoffee(); Coffee decoratedCoffee = coffee.addMilk().addSugar().addCream();`。这里的`addMilk`、`addSugar`、`addCream`等方法是装饰器类的方法,它们返回自身,使得可以不断地对咖啡对象进行装饰,每次装饰都会在原有的基础上添加新的功能或属性。
- **优点**:链式装饰的方式使得对象的功能扩展更加灵活和可组合。可以根据用户的需求灵活地添加或移除装饰,而且代码能够直观地展示出对象经过了哪些装饰和功能扩展。

http://www.kler.cn/a/428359.html

相关文章:

  • CNN-GRU卷积门控循环单元时间序列预测(Matlab完整源码和数据)
  • 2025最新 Docker 国内可用镜像源仓库地址(01月02日更新)
  • skynet 源码阅读 -- 启动主流程
  • 《机器学习数学基础》补充资料:贝叶斯分类器
  • Mac安装Homebrew
  • 【算法】字符串之227.基本计算器 -- 双栈的变形
  • application.yml 和 bootstrap.yml
  • 坚果投影仪J10如何用苹果Siri开关机并和米家联动
  • 一、Origin绘制柱状图
  • 23种设计模式之解释器模式
  • 【PlantUML系列】状态图(六)
  • 2-2-18-14 QNX系统架构之 TCP/IP 网络
  • 保护数字资产:iOS 加固在当前安全环境中的重要性
  • ChatGPT Pro是什么
  • 【机器人】系统辨识之激励轨迹设计(傅里叶级数)
  • 原生微信小程序使用原子化tailwindcss
  • 阿里云负载均衡SLB实践
  • 在 Ubuntu 18.04 上使用 Snort 的完整攻略
  • LVGL9 开关控件 (lv_switch) 使用指南
  • java+ssm+mysql水产品商城
  • 重读《人月神话》(17)-没有银弹-软件工程中的根本和次要问题
  • C/C++ 堆和优先队列
  • 深度剖析 K 近邻算法:分类、回归实战及优劣势分析
  • 电脑启动过程
  • okHttp的tcp连接池的复用
  • 记录一次使用git无权限的问题排查