上篇我们介绍了 设计模式之结构型模式篇,接下来介绍设计模式之行为型模式篇
责任链模式
责任链模式允许将请求沿着一条链传递,直到有一个对象处理它为止。每个处理者都有机会处理该请求,或者将其传递给链中的下一个处理者,每个处理者只关心自己能处理的请求,而不关心请求的来源和链中的其他处理者
它的使用场景如下:
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)应用于编程语