概念
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为
结构
抽象状态角色:定义一个接口或抽象类,用来封装环境对象中的特定状态所对应的行为
具体状态角色:实现抽象状态所对应的行为
环境角色:定义了客户程序需要的方法,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理
示例
目标:以开关门为例,门有两种状态:开、关。假定设定开门、关门状态后需要处理不同的业务逻辑,抽取出两个具体状态对象,当改变门的状态后,调用具体状态对象中的处理逻辑方法
抽象状态角色
package 设计模式.行为型模式.状态模式;
/**
* 堆代码 duidaima.com
* 状态:抽象状态角色
*/
public abstract class State {
/**
* 处理逻辑
*/
abstract void handle();
}
具体状态角色一
package 设计模式.行为型模式.状态模式;
/**
* 开门状态:具体状态角色
*/
public class OpenState extends State {
/**
* 处理逻辑
*/
@Override
void handle() {
System.out.println("打开");
}
}
具体状态角色二
package 设计模式.行为型模式.状态模式;
/**
* 关门状态:具体状态角色
*/
public class CloseState extends State {
/**
* 处理逻辑
*/
@Override
void handle() {
System.out.println("关闭");
}
}
环境角色
package 设计模式.行为型模式.状态模式;
/**
* 环境角色类
*/
public class Context {
/** 状态角色对象 */
private State state;
/**
* 设置状态
*/
void setSate(State state) {
this.state = state;
}
/**
* 执行逻辑
*/
void execute() {
this.state.handle();
}
}
测试类
package 设计模式.行为型模式.状态模式;
/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 创建环境角色
Context context = new Context();
// 设置状态
context.setSate(new OpenState());
// 执行逻辑
context.execute();
// 设置另一个状态
context.setSate(new CloseState());
// 执行逻辑
context.execute();
}
}
优缺点
优点
1.将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变状态即可改变对象的行为
2.允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块
缺点
1.增加了系统类和对象的个数
2.结构与实现比较复杂
若将状态对象的创建放到环境角色中作为静态成员变量,则在新增状态时,需要修改状态角色代码,此时不符合“开闭原则”
应用场景
1.当一个对象的行为取决于它的状态,并且它必须在运行时候根据状态改变它的行为时,可以使用状态模式
2.一个操作中有庞大的分支结构,并且这些分支决定于对象的状态时,可以使用状态模式