We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
状态模式是个人觉得所有设计模式中比较难理解的一个。容易与其他模式混淆,特别是策略模式!难归难,掌握了这个设计模式,很多问题都会变得非常简单。
状态模式的关键是要区分事物内部的状态,内部的改变往往会带来事物的行为改变。现实生活中应用状态模式的例子非常多。最常见的就是家里电灯和开关的关系。通过开关,去控制电灯的开与闭。
状态模式即允许一个对象在其内部状态改变时改变它的行为。
上面这个例子用代码实现也比较简单,大部分人会使用if else语句去完成。对于这个例子来说没什么问题。
将上面的例子稍微复杂化,暖白交替的灯显示生活中也很常见。按一下开关是白色,再按一下是暖色,再按一下变成暖白混合色,再按一下就关闭了。脑子里面可以简单的过一下这个逻辑!用代码编写这段逻辑就是四个if else的串联:
Light.prototype.pressButton = () => { if (this.state === 'off') { this.state = 'white'; } else if (this.state === 'white') { this.state = 'warm'; } else if (this.state === 'warm') { this.state = 'mixedWhiteWarm'; } else if (this.state === 'mixedWhiteWarm') { this.state = 'off'; } }
要是再添加一个颜色,就要修改函数内部的逻辑,这显示不是我们想要的。也违反了“开放-封闭”原则。而且pressButton也会越来越庞大。
现在我们用状态模式来修改这个例子。
var OffState = (light) => { this.light = light; } OffState.prototype.pressButton = () => { this.light.setState(this.light.Warm); } var Warm = (light) => { this.light = light; } Warm.prototype.pressButton = () => { this.light.setState(this.light.White); } var White = (light) => { this.light = light; } White.prototype.pressButton = () => { this.light.setState(this.light.MixedWhiteWarm); } var MixedWhiteWarm = (light) => { this.light = light; } MixedWhiteWarm.prototype.pressButton = () => { this.light.setState(this.light.offState); }
接下来写Light类
var Light = () => { this.offState = new OffState(this); this.Warm = new Warm(this); this.White = new White(this); this.MixedWhiteWarm = new MixedWhiteWarm(this); this.button = null; }
添加一个初始函数
Light.prototype.init = () => { var button = document.createElement('button'); this.button = document.body.appendChild(button); this.button.innerHTML = '按钮'; this.currentState = this.offState; this.button.onclick = () => { this.currentState.pressButton(); } }
最后再加一个setState方法:
Light.prototype.setState = (newState) => { this.currentState = newState; }
测试代码:
var light = new Light(); light.init();
这就使用状态模式完成了灯的例子。好处很明显:可以使每一种状态和它对应的行为之间的关系局部化,这些行为被分散和封装在各自对应的状态类之中,便于阅读和管理。
这时如果需要再加一种蓝色灯,只需要添加一个状态类和在Light构造函数中加一个状态。
状态模式和策略模式经常不知怎么区分。它们的相同点是都有一个上下文,一些策略或者状态类,上下文把请求委托给这些类来执行。
状态模式和策略模式的区别是后者中各个策略类之间是平等且平行的,它们之间没有任何的联系,所以客户必须熟知每一个策略的作用细节。而在状态模式中,初始时就封装好了所有的状态以及对应的行为,状态之间的转换也早被规定好;改变状态的行为发生在模式内部,用户不需要了解状细节。
状态模式比较难,但是应用非常广泛。比如说现在火热的前端框架react,对于每一个组件来说,都是一个状态机!state表示react组件内部的一种状态,通过组件内的getInitialState函数,可以为组件的初始状态赋值,当组件的状态发生改变时,组件会重新渲染。
开发中,遇到很多种状态转换时,可以考虑使用状态模式,理清楚状态以及行为的关系,接下来的工作就会变得简单很多!
The text was updated successfully, but these errors were encountered:
No branches or pull requests
定义
状态模式是个人觉得所有设计模式中比较难理解的一个。容易与其他模式混淆,特别是策略模式!难归难,掌握了这个设计模式,很多问题都会变得非常简单。
状态模式的关键是要区分事物内部的状态,内部的改变往往会带来事物的行为改变。现实生活中应用状态模式的例子非常多。最常见的就是家里电灯和开关的关系。通过开关,去控制电灯的开与闭。
状态模式即允许一个对象在其内部状态改变时改变它的行为。
举例
上面这个例子用代码实现也比较简单,大部分人会使用if else语句去完成。对于这个例子来说没什么问题。
将上面的例子稍微复杂化,暖白交替的灯显示生活中也很常见。按一下开关是白色,再按一下是暖色,再按一下变成暖白混合色,再按一下就关闭了。脑子里面可以简单的过一下这个逻辑!用代码编写这段逻辑就是四个if else的串联:
要是再添加一个颜色,就要修改函数内部的逻辑,这显示不是我们想要的。也违反了“开放-封闭”原则。而且pressButton也会越来越庞大。
现在我们用状态模式来修改这个例子。
接下来写Light类
添加一个初始函数
最后再加一个setState方法:
测试代码:
这就使用状态模式完成了灯的例子。好处很明显:可以使每一种状态和它对应的行为之间的关系局部化,这些行为被分散和封装在各自对应的状态类之中,便于阅读和管理。
这时如果需要再加一种蓝色灯,只需要添加一个状态类和在Light构造函数中加一个状态。
优点
缺点
性能优化
对比策略模式
状态模式和策略模式经常不知怎么区分。它们的相同点是都有一个上下文,一些策略或者状态类,上下文把请求委托给这些类来执行。
状态模式和策略模式的区别是后者中各个策略类之间是平等且平行的,它们之间没有任何的联系,所以客户必须熟知每一个策略的作用细节。而在状态模式中,初始时就封装好了所有的状态以及对应的行为,状态之间的转换也早被规定好;改变状态的行为发生在模式内部,用户不需要了解状细节。
小结
状态模式比较难,但是应用非常广泛。比如说现在火热的前端框架react,对于每一个组件来说,都是一个状态机!state表示react组件内部的一种状态,通过组件内的getInitialState函数,可以为组件的初始状态赋值,当组件的状态发生改变时,组件会重新渲染。
开发中,遇到很多种状态转换时,可以考虑使用状态模式,理清楚状态以及行为的关系,接下来的工作就会变得简单很多!
The text was updated successfully, but these errors were encountered: