状态模式(State)
2020-07-22 本文已影响0人
秀儿2020
定义
允许一个对象在其内部状态改变时,改变他的行为,对象看起来似乎是修改了他的类。
本质
根据状态来分离和选择行为
登场角色
-
State(状态)
定义了根据不同状态进行不同处理的接口
-
ConcreteState(具体的状态)
实现状态接口,表示各个具体的状态。
-
Context(状况、前后关系、上下文)
实现状态处理的类
示例代码
/**
* 状态
* 电视状态接口,定义了电视操作
*/
public interface TvState {
public void nextChange();
public void prevChange();
public void turnUp();
public void turnDown();
}
/**
* 具体的状态1
*/
public class PowerOnState implements TvState{
@Override
public void nextChange() {
System.out.println("上一个频道");
}
@Override
public void prevChange() {
System.out.println("下一个频道");
}
@Override
public void turnUp() {
System.out.println("调高音量");
}
@Override
public void turnDown() {
System.out.println("调低音量");
}
}
/**
* 具体的状态2
*/
public class PowerOffState implements TvState{
@Override
public void nextChange() {
}
@Override
public void prevChange() {
}
@Override
public void turnUp() {
}
@Override
public void turnDown() {
}
}
/**
* 电视遥控器
*/
public class TvController implements PowerController{
private TvState tvState;
public void setTvState(TvState tvState) {
this.tvState = tvState;
}
@Override
public void powerOn() {
setTvState(new PowerOnState());
System.out.println("开机啦");
}
@Override
public void powerOff() {
setTvState(new PowerOffState());
System.out.println("关机啦");
}
public void nextChange() {
tvState.nextChange();
}
public void prevChange() {
tvState.prevChange();
}
public void turnUp() {
tvState.turnUp();
}
public void turnDown() {
tvState.turnDown();
}
}
public class Client {
public static void main(String[] args){
TvController tvController = new TvController();
//设置开机状态
tvController.powerOn();
tvController.nextChange();//下一个频道
tvController.turnUp(); //调高音量
//设置关机状态
tvController.powerOff();
//调低音量,此时不会生效
tvController.turnDown();
}
}
运行结果
开机啦
上一个频道
调高音量
关机啦
功能
分离状态的行为,通过维护状态的变化,来调用不同的状态对应的不同实现。状态和行为是相关联的,他们的关系可以描述为:状态决定行为。
由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变,看起来,同一个对象,在不同的运行时刻,行为是不是不一样的,就像是类被修改了一样。
优点
- 简化应用逻辑控制,通过使用单据的类来封装一个状态的处理。
- 更好的分离状态和行为,通过设置状态类的所有接口,来把状态和状态对应的行为分离开,把所有与一个特定的状态相关的行为都放入一个对象中,使得应用程序在控制的时候,只需要关心状态的切换,而不用关心这个状态对应的真正处理。
- 更好的扩展性。引入了状态处理的公共接口后,使得扩展新的状态变得非常容易,只需要新增加一个实现状态处理的公共接口的实现类,然后在进行状态维护的地方,设置状态变化到这个新的状态即可。
- 显示化进行状态的切换。
缺点
- 一个状态对应一个状态处理类,使类文件增多。
何时使用
- 如果一个对象的行为取决于它的状态,而且它必须在运行时刻根据状态来改变它的行为,可以使用状态模式。
- 如果一个操作中含有大量的分支语句,而且这些分支依赖于它的状态,可以使用状态模式。