定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。状态模式是一种对象行为型模式。
角色
状态模式角色分类如下
- 抽象状态接口。定义状态的抽象行为。使用抽象类或者接口(interface)实现。
- 具体状态接口。实现了抽象状态。
- 环境类。聚合了一个状态引用,环境类可以根据环境的变化,动态改变状态引用所指向的具体状态对象。环境对象改变内部状态的特性,使该模式被定义为行为型设计模式。
UML
实现
以电热水器为例实现,热水器包括了加热和停止加热两个状态。
package design.patten.state;
/**
* desc : 热水器状态接口
* Created by tiantian on 2018/9/1
*/
public interface WaterHeaterState {
void showTemperature();
void setTemperature(int temperature);
}
/**
* desc : 加热状态具体实现
* Created by tiantian on 2018/9/1
*/
public class Heating implements WaterHeaterState {
private int temperature;
@Override
public void showTemperature() {
System.out.println(String.format("Water is heating and temperature is %d now", temperature));
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
}
/**
* desc : 停止加热状态
* Created by tiantian on 2018/9/1
*/
public class StopHeating implements WaterHeaterState{
private int temperature;
@Override
public void showTemperature() {
System.out.println(String.format("Water is heating and temperature is %d now", temperature));
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
}
/**
* desc : 热水器(状态模式中的环境类)
* Created by tiantian on 2018/9/1
*/
public class WaterHeater {
private WaterHeaterState state;
private int temperature = 0;
public void open() {
setState(new Heating());
Thread t = new Thread(() -> {
while (true) {
this.heating();
state.setTemperature(temperature);
try {
// 休眠若干时间,模拟加热过程
Thread.sleep(1000);
showTemper();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (temperature == 100) {
setState(new StopHeating());
System.out.println("Heating done! temperature is "+ temperature);
break;
}
}
});
t.start();
}
public void setState(WaterHeaterState state) {
this.state = state;
}
public WaterHeaterState getState() {
return state;
}
public void heating() {
temperature += 10;
}
public void showTemper() {
state.showTemperature();
}
}
/**
* desc : 热水器测试
* Created by tiantian on 2018/9/1
*/
public class WaterHeaterTest {
public static void main(String[] args) throws InterruptedException {
WaterHeater wh = new WaterHeater();
wh.open();
}
}
// output: 程序陆续输出如下
// Water is heating and temperature is 10 now
// Water is heating and temperature is 20 now
// Water is heating and temperature is 30 now
// Water is heating and temperature is 40 now
// Water is heating and temperature is 50 now
// Water is heating and temperature is 60 now
// Water is heating and temperature is 70 now
// Water is heating and temperature is 80 now
// Water is heating and temperature is 90 now
// Water is heating and temperature is 100 now
// Heating done! temperature is 100
java编程思想中的例子:
//相当于状态模式中的state
class Actor {
public void act(){
}
}
//相当于状态模式中的ConcreteStateSubclassess
class HappyActor extends Actor{
public void act(){
System.out.println("HappyActor");
}
}
class SadActor extends Actor{
public void act(){
System.out.println("SadActor");
}
}
//相当于状态模式中的Context
class Stage{
private Actor actor=new HappyActor();
//改变引用actor的指向的具体类型
public void change(){
actor=new SadActor();
}
//根据状态的不同执行不同的行为
public void performPlay(){
actor.act();
}
}
public class Transmogrify {
/**
* @param args
*/
public static void main(String[] args) {
Stage stage=new Stage();
stage.performPlay();
stage.change();
stage.performPlay();
}
}
总结
状态模式与策略模式及其相似,从UML结构也可以看出来。但两者又是有区别的。策略模式封装了若干算法族,让使用算法的用户自己选择具体的算法(策略),用户要知晓具体算法的作用。而状态模式对用户完全透明,状态的转换完全由环境对象控制。