允许对象在内部状态改变时,改变它的行为
大厅灯光
在酒店的大厅里面是会有一个开关控制灯光、一般情况下一个开关可以控制一个灯光很多场景,比如按一下是打开微弱灯光、再按一下变成强光、继续再来一下灯光被关闭、所以我们很容易写出下方代码
一梭子写法
class Light{
constructor(){
this.state = 'off'
}
buttonWasPressed(){
if(this.state === 'off'){
console.log('弱光')
this.state = 'weakLight'
}else if(this.state === 'weakLight'){
console.log('强光')
this.state = 'strongLight'
}else{
console.log('关闭')
this.state = 'off'
}
}
}
随着条件的增多、if-else会越来越多、同时也违反了开放-封闭的原则,所有的跟状态的有关的行为都封装在buttonWasPressed方法
状态机方式
// 弱光类
class OffLightState{
constructor(light){
this.light = light
}
bottonWasPressed(){
console.log('弱光')
// 设置下次执行的光亮
this.light.setState(this.light.weakLightState)
}
}
class WeakLightState{
constructor(light){
this.light = light
}
bottonWasPressed(){
console.log('强光')
// 设置下次执行的光亮
this.light.setState(this.light.strongLightState)
}
}
class StrongLightState{
constructor(light){
this.light = light
}
bottonWasPressed(){
console.log('关灯')
// 设置下次执行的光亮
this.light.setState(this.light.offLightState)
}
}
class Light{
constructor(){
this.offLightState = new OffLightState(this);
this.weakLightState = new WeakLightState(this);
this.strongLightState = new StrongLightState(this);
this.button = null;
this.currState = null;
}
init(){
this.button = document.createElement('div');
this.button.innerHTML = '开关按钮'
this.currState = this.offLightState;
document.body.appendChild(this.button)
this.button.onclick = ()=>{
this.currState.bottonWasPressed()
}
}
setState( newSate ){
this.currState = newSate
}
}
let light = new Light()
light.init()