本文深入解析JavaScript中的状态模式与适配器模式。状态模式通过封装状态转换逻辑,使对象在状态改变时行为随之改变,有效避免Context类膨胀并提升代码可维护性。适配器模式则用于解决接口不兼容问题,通过封装现有对象实现接口转换,符合开闭原则。
一、状态模式
该模式的核心在于允许对象在内部状态发生变化时,其行为表现也随之改变,从外部观察,该对象仿佛改变了其所属的类。
1.基本实现
//下面以一个开灯程序演示状态模式
//灯共用三种状态,分别是‘关闭',‘弱光‘和'强光‘。每次按下开关按钮都会换挡。
let OfflightState = function (light) {
this.light = light;
}
OfflightState.prototype.buttonPressed = function () {
console.light('弱光');
this.light.setState(this.light.weakLightState);
}
let WeakLightState = function (light) {
this.light = light;
}
WeakLightState.prototype.buttonPressed = function () {
console.log('强光')
this.light.setState(this.light.strongLightState);
}
let StrongLightState = function (light) {
this.light = light;
}
StrongLightState.prototype.buttonPressed = function () {
console.log('关闭');
this.light.setState(this.light.offlightState)
}
let Light = function () {
this.offlightState = new OfflightState(this);
this.weakLightState = new WeakLightState(this);
this.strongLightState = new StrongLightState(this);
this.button = null;
}
Light.prototype.init = function () {
let button = document.createElement('button');
self = this;
this.button = document.body.appendChild(button);
this.button.innerHTML = '开关';
this.button.currState = this.offlightState;
this.button.onclick = function () {
self.currState.buttonPressed;
}
}
Light.prototype.setState = function (newState) {
this.currState = newState;
}
let light = new Light();
light.init();
上述代码构建了一个基础的状态模式框架。状态的切换规则已在各个独立的状态类中预先定义,主体对象无需关注具体的切换细节。若未来需要引入新状态,只需编写对应的状态类并将其集成到现有代码结构中即可,无需修改原有逻辑。
2.状态模式的优缺点
(1)状态模式明确了状态与行为之间的对应关系,并将它们封装在独立的类中。通过新增状态类,可以便捷地扩展新的状态及其转换逻辑。
(2)该模式有助于避免Context类无限膨胀。状态切换的逻辑被分散到各个状态类中,从而消除了Context中原本冗长的条件分支语句。
(3)使用对象实例替代字符串来标识当前状态,使得状态的切换过程更加直观清晰。
(4)Context中的请求动作与状态类中封装的行为可以独立演变,互不干扰,提高了代码的灵活性和可维护性。
3.状态模式中的性能优化点
(1)状态的创建时机可根据实际场景灵活选择:既可以按需延迟创建,也可以在初始化阶段一次性创建完毕。
(2)state对象实例可以在多个类之间进行共享,以减少内存开销。
二、适配器模式
该模式主要用于解决两个软件实体之间接口不兼容的问题,使原本因接口限制无法一起工作的类能够协同工作。
适配器模式的应用
let googleMap = {
show: function () {
console.log('开始渲染谷歌地图');
}
}
let baiduMap = {
show: function () {
console.log('开始渲染百度地图');
}
}
let renderMap = function (map) {
map.show();
}
/**
* 以上代码段实现了渲染不同地图的功能。现在假设BaiduMap的api改成了display,修改源代码势必不太符合开闭原则,这时候我们可以通过新建一个适配器来达到目的
*/
let baiduMapAdapter = {
show: function () {
return baiduMap.display();
}
}
renderMap(baiduMapAdapter);
至此,关于JavaScript状态模式及适配器模式的使用讲解已完成。如需了解更多JavaScript状态模式相关内容,请搜索本站过往文章或继续阅读后续相关文章。感谢大家的支持!