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

链式设计

  1. 定义和概念

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

    javascript 复制代码
    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`),用于连接下一个审批环节,如:
java 复制代码
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`等方法是装饰器类的方法,它们返回自身,使得可以不断地对咖啡对象进行装饰,每次装饰都会在原有的基础上添加新的功能或属性。
- **优点**:链式装饰的方式使得对象的功能扩展更加灵活和可组合。可以根据用户的需求灵活地添加或移除装饰,而且代码能够直观地展示出对象经过了哪些装饰和功能扩展。
相关推荐
杨充1 天前
10.可测试性实战设计
设计模式·开源·代码规范
杨充1 天前
9.重构十二式的实战
设计模式·开源·代码规范
杨充1 天前
6.设计原则的全景图
设计模式·开源·全栈
杨充1 天前
2.面向对象的特性
设计模式
杨充1 天前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充1 天前
8.反模式与坏味道
设计模式·开源·代码规范
杨充1 天前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式