JavaScript设计模式之命令模式和状态模式详解

这篇文章主要为大家介绍了JavaScript设计模式之命令模式和状态模式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助!

命令模式

命令模式介绍

命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及执行可撤销的操作。

也就是说改模式旨在将函数的调用、请求和操作封装成一个单一的对象,然后对这个对象进行一系列的处理。此外,可以通过调用实现具体函数的对象来解耦命令对象与接收对象。

代码实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cmd-demo</title>
</head>
<body>
<div>
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
</div>
<script>
var btn1 = document.getElementById('btn1')
var btn2 = document.getElementById('btn2')
// 定义一个命令发布者(执行者)的类
class Executor {
setCommand(btn, command) {
btn.onclick = function() {
command.execute()
}
}
}
// 定义一个命令接收者
class Menu {
refresh() {
console.log('刷新菜单')
}
addSubMenu() {
console.log('增加子菜单')
}
}
// 定义一个刷新菜单的命令对象的类
class RefreshMenu {
constructor(receiver) {
// 命令对象与接收者关联
this.receiver = receiver
}
// 暴露出统一的接口给命令发布者Executor
execute() {
this.receiver.refresh()
}
}
// 定义一个增加子菜单的命令对象的类
class AddSubMenu {
constructor(receiver) {
// 命令对象与接收者关联
this.receiver = receiver
}
// 暴露出统一的接口给命令发布者Executor
execute() {
this.receiver.addSubMenu()
}
}
var menu = new Menu()
var executor = new Executor()
var refreshMenu = new RefreshMenu(menu)
// 给按钮1添加刷新功能
executor.setCommand(btn1, refreshMenu)
var addSubMenu = new AddSubMenu(menu)
// 给按钮2添加增加子菜单功能
executor.setCommand(btn2, addSubMenu)
</script>
</body>
</html>

状态模式

状态模式介绍

状态模式(State)允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类。

代码实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>state-demo</title>
</head>
<body>
<button id="btn">开关</button>
<script>
// 定义一个关闭状态的类   
class OffLightState {
constructor(light) {
this.light = light
}
// 每个类都需要这个方法,在不同状态下按都需要触发这个方法
pressBtn() {
this.light.setState(this.light.weekLightState)
console.log('开启弱光')
}
}
// 定义一个弱光状态的类   
class WeekLightState {
constructor(light) {
this.light = light
}
pressBtn() {
this.light.setState(this.light.strongLightState)
console.log('开启强光')
}
}
// 定义一个强光状态的类
class StrongLightState {
constructor(light) {
this.light = light
}
pressBtn() {
this.light.setState(this.light.offLightState)
console.log('关闭电灯')
}
}
class Light {
constructor() {
this.offLightState = new OffLightState(this)
this.weekLightState = new WeekLightState(this)
this.strongLightState = new StrongLightState(this)
this.currentState = null
}
setState(newState) {
this.currentState = newState
}
init() {
this.currentState = this.offLightState
}
}
let light = new Light()
light.init()
var btn = document.getElementById('btn')
btn.onclick = function() {
light.currentState.pressBtn()
}
</script>
</body>
</html>

小结

通过定义不同的状态类,根据状态的改变而改变对象的行为,不必把大量的逻辑都写在被操作对象的类中,而且容易增加新的状态符合开放封闭原则

Win11扬声器无声音且无插座信息的解决方法 网站建设

Win11扬声器无声音且无插座信息的解决方法

Win11扬声器无插座信息怎么解决?近期有部分Win11用户跟小编反映,自己的电脑在更新好系统并重启开机后,出现了系统没有声音的情况,而且还显示扬声器无插座信息,音频服务未响应。对此有没有什么方法解决...
Spring@value用法示例详解 网站建设

Spring@value用法示例详解

为了简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性。 一、两种使用方法 1、@Value(“#{c...
SpringBoot整合Mybatis简单实现增删改查 网站建设

SpringBoot整合Mybatis简单实现增删改查

为什么要学SpringBoot和Mybatis呢,我觉得作为一个合格的后端程序员增删改查(CRUD)肯定是要会的,而且是最基本的一项技能,不然怎么完成给你分配的需求呢;而为什么选择SpringBoot...
使用Python如何实现获取照片位置信息 网站建设

使用Python如何实现获取照片位置信息

通过一张照片居然发现女友在宿舍里没去上课!强大的照片位置信息获取,快来一起学习吧! 一、exifread函数库 要怎样获得拍摄图片的GPS呢?这里我们需要exifread 库,这个就是用来提取 G...