从前端视角看设计模式之行为型模式篇

上篇我们介绍了 设计模式之结构型模式篇,接下来介绍设计模式之行为型模式篇

责任链模式

责任链模式允许将请求沿着一条链传递,直到有一个对象处理它为止。每个处理者都有机会处理该请求,或者将其传递给链中的下一个处理者,每个处理者只关心自己能处理的请求,而不关心请求的来源和链中的其他处理者


它的使用场景如下:

1)当有多个对象可以处理请求,且具体由哪个对象处理由运行时决定时

2)当需要向多个对象中的一个提交请求,而不想明确指定接收者时

3)在实际应用中,广泛应用于权限管理、审批流程等场景


责任链模式包含以下几个主要角色:

1)抽象处理者

负责定义处理请求的接口,通常包含一个指向下一个处理者的引用,若不能处理请求,则将请求传递给下一个处理者

2)具体处理者

继承自抽象处理者,实现具体的请求处理逻辑

3)客户端

向链上的处理者发出请求


通过以下这个审批系统来理解责任链模式,涉及多个审批角色,如经理、总监、CEO,每个角色都有不同的审批权限

1)定义请求类

包含请求的内容

// 定义请求类
class Request {
    constructor(amount, description) {
      this.amount = amount
      this.description = description
    }
}

2)定义抽象处理者

声明一个方法来处理请求,并定义一个指向下一个处理者的引用

// 定义抽象处理者类
class Approver {
    constructor(name) {
      this.name = name
      this.nextApprover = null // 下一位审批者
    }
    setNext(approver) {
      this.nextApprover = approver
    }
    // 处理请求的方法,具体逻辑由子类实现
    approve(request) {
      if (this.nextApprover) {
        this.nextApprover.approve(request)
      } else {
        console.log('没有审批者可以处理这个请求')
      }
    }
}

3)定义具体处理者

实现请求的处理逻辑,若无法处理则交给下一个处理者

// 定义具体处理者类:经理、总监、CEO
class Manager extends Approver {
    approve(request) {
      if (request.amount <= 1000) {
        console.log(`${this.name} 批准了 ${request.description},金额: ${request.amount}`)
      } else if (this.nextApprover) {
        console.log(`${this.name} 无权批准该请求,转交给 ${this.nextApprover.name}`)
        this.nextApprover.approve(request)
      }
    }
}
class Director extends Approver {
    approve(request) {
      if (request.amount <= 5000) {
        console.log(`${this.name} 批准了 ${request.description},金额: ${request.amount}`)
      } else if (this.nextApprover) {
        console.log(`${this.name} 无权批准该请求,转交给 ${this.nextApprover.name}`)
        this.nextApprover.approve(request)
      }
    }
} 
class CEO extends Approver {
    approve(request) {
      console.log(`${this.name} 批准了 ${request.description},金额: ${request.amount}`)
    }
}

4)客户端

创建并发出请求

// 客户端代码
const manager = new Manager('经理')
const director = new Director('总监')
const ceo = new CEO('CEO')

// 设定审批链:经理 -> 总监 -> CEO
manager.setNext(director)
director.setNext(ceo)

// 发起请求
const request1 = new Request(500, '购买办公设备')
manager.approve(request1)

const request2 = new Request(3000, '购买电脑')
manager.approve(request2)

const request3 = new Request(10000, '购买企业级服务器')
manager.approve(request3)

执行代码,运行结果如下:

在这里插入图片描述

命令模式

命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作


它的使用场景如下:

1)当需要对行为进行记录、撤销/重做或事务处理时


命令模式包含以下几个主要角色:

1)命令

命令接口,声明一个执行操作的方法

2)具体命令

实现命令接口,负责执行具体操作,通常包含对接收者的引用,通过调用接收者的方法来完成请求的处理

3)接收者

知道如何执行与请求相关的操作,实际执行命令的对象

4)调用者

发送命令的对象,它包含了一个命令对象并能触发命令的执行,调用者并不直接处理请求,而是通过将请求传递给命令对象来实现

5)客户端

创建具体命令对象并设置其接收者,将命令对象交给调用者执行


通过以下这个遥控器控制家电来理解命令模式,将每一个开关的操作封装成命令对象,并通过遥控器来调用这些命令

1)命令接口

定义一个命令接口,包含一个执行方法execute()

// 定义命令接口
class Command {
    execute() {
      throw new Error("execute() 必须被实现")
    }
}

2)具体命令

实现命令接口,具体实现每个命令的操作

// 具体命令 - 开灯命令
class LightOnCommand extends Command {
    constructor(light) {
      super()
      this.light = light
    }
    execute() {
      this.light.turnOn()
    }
}
// 具体命令 - 关灯命令
class LightOffCommand extends Command {
    constructor(light) {
      super()
      this.light = light
    }
    execute() {
      this.light.turnOff()
    }
}
// 具体命令 - 开风扇命令
class FanOnCommand extends Command {
    constructor(fan) {
      super()
      this.fan = fan
    }
    execute() {
      this.fan.turnOn()
    }
}
// 具体命令 - 关风扇命令
class FanOffCommand extends Command {
    constructor(fan) {
      super()
      this.fan = fan
    }
    execute() {
      this.fan.turnOff()
    }
}

3)接收者

具体的家电设备(灯和风扇),每个设备都有开和关的操作

// 接收者 - 灯类
class Light {
    turnOn() {
      console.log("灯已打开")
    }
    turnOff() {
      console.log("灯已关闭")
    }
}
// 接收者 - 风扇类
class Fan {
    turnOn() {
      console.log("风扇已打开")
    }
    turnOff() {
      console.log("风扇已关闭")
    }
}

4)调用者

遥控器,通过调用命令对象的execute()方法来执行命令

// 调用者 - 遥控器类
class RemoteControl {
    constructor() {
      this.command = null
    }
    setCommand(command) {
      this.command = command
    }
    pressButton() {
      this.command.execute()
    }
}

5)客户端

客户端创建命令对象,并设置对应的设备

// 客户端代码
const light = new Light()
const fan = new Fan()

// 创建命令对象
const lightOn = new LightOnCommand(light)
const lightOff = new LightOffCommand(light)
const fanOn = new FanOnCommand(fan)
const fanOff = new FanOffCommand(fan)

// 创建遥控器
const remote = new RemoteControl()

// 按下按钮执行开关命令
remote.setCommand(lightOn)
remote.pressButton()  // 灯已打开

remote.setCommand(fanOn)
remote.pressButton()  // 风扇已打开

remote.setCommand(lightOff)
remote.pressButton()  // 灯已关闭

remote.setCommand(fanOff)
remote.pressButton()  // 风扇已关闭

解释器模式

解释器模式用于给定语言的句法(语法规则)提供一个解释器,这个解释器使用该表示来解释语言中的句子


它的使用场景如下:

1)当某一特定类型的问题频繁出现,并且可以通过一种简单的语言来表达这些问题的实例时

2)应用于编程语

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值