State mode
State mode: Each state in an object is encapsulated into classes, and changes in the internal state will lead to different behaviors.
Advantages: Using objects instead of strings to record the current state is easy to maintain.
Disadvantage: A large number of state class objects need to be written
Scene demo
A certain brand of electric light, press the button to turn on the weak light, press two buttons to turn on the strong light, press three buttons to turn off the light.
// Encapsulating states into different classes const weakLight = function(){ this.light = light } weakLight.prototype.press = function(){ console.log('Open strong light') this.light.setState(this.light.strongLight) } const strongLight = function(){ this.light= light } strongLight.prototype.press = function(){ console.log('Turn off the lights') this.light.setState(this.light.offLight) } const offLight = function(){ this.light= light } offLight.prototype.press = function(){ console.log('Open weak light') this.light.setState(this.light.weakLight) } const Light = function(){ this.weakLight = new weakLight(this) this.strongLight = new strongLight(this) this.offLight = new offLight(this) this.currentState = this.offLight //Initial state } Light.prototype.init = function(){ const btn = doucment.createElement('button') btn.innerHTML = 'Button' document.body.append(btn) const self = this btn.addEventListener('click',function(){ self.currentState.press() }) } Light.prototype.setState = function(state){ this.currentState = state } const light = new Light() light.init()
State Patterns for Non-Object-Oriented Implementation
// With the delegation mechanism of javascript, the state pattern can be implemented as follows const obj = { 'weakLight': { press: function(){ console.log('Open strong light') this.currentState = obj.strongLight } }, 'strongLight': { press: function(){ console.log('Turn off the lights') this.currentState = obj.offLight } }, 'offLight': { press: function(){ console.log('Open weak light') this.currentState = obj.weakLight } }, } const Light = function(){ this.currentState = obj.offLight } Light.prototype.init = function(){ const btn = document.createElement('button') btn.innerHTML = 'Button' document.body.append(btn) const self = this btn.addEventListener('click',function(){ self.currentState.press.call(self) //Delegate through call }) } const light = new Light() light.init()