概念与特点
概念:
状态模式指的是当控制一个对象状态转换的条件表达式过于复杂时,将判断逻辑提取出来,放到一系列的状态类中。
特点:
- 不同状态的行为分隔开,满足单一职责原则。
- 减少对象之间的相互依赖,将不同状态引入独立的对象使得状态转换更加明确。
- 方便拓展,建立新的子类可以很容易地添加新的状态和转换。
结构与实现
结构:
状态模式包含环境角色、抽象状态和具体状态。
环境角色:定义初始化状态,管理状态,并将与状态相关的操作委托给当前状态对象来处理。
抽象状态:封装状态的行为。
具体状态:实现抽象状态所对应的行为。
案例:
实现一个判断学生分数状态的功能。分数小于 60 分为【不及格】;分数大于 60 分小于 90 分为【中等】;分数大于等于 90 分为【优秀】。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>React App</title>
</head>
<body>
<script>
class StoreContext{
constructor(){
this.state = new LowState(this);
}
setState(state){
this.state = state;
}
getState(){
return this.state;
}
//分数合计
add(score){
this.state.addScore(this,score);
}
}
class Score{
//抽象方法,检查当前状态
checkState(context){
}
//分数合计-状态之间的业务逻辑
addScore(context,score){
console.log("当前分数:"+this.score+",当前状态:"+this.stateName);
console.log("加上"+score+"之后,");
this.score += score;
this.checkState(context);
console.log("分数为:"+this.score+",状态为:"+context.getState().stateName);
}
}
class LowState extends Score{
constructor(state){
super(state);
this.stateName = "不及格";
this.score = state.score||0;
}
checkState(context){
if(this.score>=90 ){
//大于90分时,状态为【优秀】
context.setState(new HighState(this))
}else if(this.score>=60){
//大于60分时,状态为【中等】
context.setState(new MiddleState(this))
}
}
}
class MiddleState extends Score{
constructor(state){
super(state);
this.stateName = "中等";
this.score = state.score;
}
checkState(context){
if(this.score<60 ){
//小于60分时,状态为【不及格】
context.setState(new LowState(this))
}else if(this.score>=90){
context.setState(new HighState(this))
}
}
}
class HighState extends Score{
constructor(state){
super(state);
this.stateName = "优秀";
this.score = state.score;
}
checkState(context){
if(this.score<60 ){
context.setState(new LowState(this))
}else if(this.score<90){
context.setState(new MiddleState(this))
}
}
}
class Customer{
static main(){
let context = new StoreContext();
context.add(30);
context.add(40);
context.add(-60);
context.add(100);
}
}
Customer.main();
</script>
</body>
</html>
应用场景
- 当一个对象的行为取决于它的状态,并且在运行的时候会根据状态改变行为时。
- 一个对象含有庞大的分支结构,并且这些分支决定于对象的状态时。
应用实例
暂无。
总结
常见的前端功能中的状态大多是【是/否】两种,一般都是用 if else 来解决。所以可能用不到比较复杂的状态模式。但是即便只有两种状态,如果状态相关的行为比较复杂,也是可以使用状态模式将其抽离出来。另外如果状态比较多的情况下也适合使用状态模式将不同的状态行为进行分离。
【环境类】:
1、在构造函数中初始化状态(将当前环境作为参数传入)。
1、提供设置状态、获取状态的方法,
2、提供业务方法,调用抽象类的业务方法(将上下文环境和业务参数传入)。
【抽象状态类】:
1、提供业务方法,供环境类调用,在内部调用具体状态类的方法改变状态。
【具体状态类】:
1、提供改变状态的方法,根据传入参数,使用环境类设置状态。