允许一个对象在其内部状态改变时改变它的行为。
状态模式将对象的状态封装成独立的类,并使它们可以互相转换
// 定义状态接口
class State {
constructor() {
if (this.constructor === State) {
throw new Error('不能实例化抽象类');
}
}
// 定义状态方法
handle(context) {
throw new Error('必须实现 handle 方法');
}
}
// 具体状态类 A
class ConcreteStateA extends State {
constructor() {
super();
}
// 实现状态方法
handle(context) {
console.log('执行具体状态 A 的方法');
context.setState(new ConcreteStateB());
}
}
// 具体状态类 B
class ConcreteStateB extends State {
constructor() {
super();
}
// 实现状态方法
handle(context) {
console.log('执行具体状态 B 的方法');
context.setState(new ConcreteStateA());
}
}
// 上下文类
class Context {
constructor() {
this.state = new ConcreteStateA();
}
// 设置状态方法
setState(state) {
this.state = state;
}
// 执行状态方法
request() {
this.state.handle(this);
}
}
// 使用状态模式
let context = new Context();
context.request();
context.request();
context.request();
class CoffeeMaker {
constructor() {
/**
这里略去咖啡机中与咖啡状态切换无关的一些初始化逻辑
**/
// 初始化状态,没有切换任何咖啡模式
this.state = 'init';
// 初始化牛奶的存储量
this.leftMilk = '500ml';
}
//将状态作为属性放进去
stateToProcessor = {
that: this,
american() {
// 尝试在行为函数里拿到咖啡机实例的信息并输出
console.log('咖啡机现在的牛奶存储量是:', this.that.leftMilk)
console.log('我只吐黑咖啡');
},
latte() {
this.american()
console.log('加点奶');
},
vanillaLatte() {
this.latte();
console.log('再加香草糖浆');
},
mocha() {
this.latte();
console.log('再加巧克力');
}
}
// 关注咖啡机状态切换函数
changeState(state) {
this.state = state;
if (!this.stateToProcessor[state]) {
return;
}
this.stateToProcessor[state]();
}
}
const mk = new CoffeeMaker();
mk.changeState('latte');