23个java设计模式(十七)-- 状态模式

2016年03月24日 原创
关键词: java 设计模式
摘要 状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

一、概述。

状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

一个对象的状态依赖于它的变量的取值情况,对象在不同的运行环境中,可能具有不同的状态。

状态模式的关键是将对象的状态封装成为独立的类,对象调用方法时,可以委托当前对象所具有的状态调用相应的方法,使当前对象看起来好像修改了它的类。

二、状态模式的结构。

状态模式包括三种角色:

  • 环境(Context):环境是一个类,该类含有抽象状态(State)声明的变量,可以应用任何具体状态类的实例。用户对该环境(Context)类的实例在某种状态下的行为感兴趣。
  • 抽象状态(State):抽象状态是一个接口或抽象类。抽象状态中定义了与环境(Context)的一个特定状态相关的若干个方法。
  • 具体状态(Concrete State):具体状态是实现(扩展)抽象状态(抽象类)的类。

三、示例程序。

环境(Context)

Thermometer.java

public class Thermometer {
	private TemperatureState state;
	public void showMsg() {
		System.out.println("*******************");
		state.showTemperature();
		System.out.println("*******************");
	}
	public TemperatureState getState() {
		return state;
	}
	public void setState(TemperatureState state) {
		this.state = state;
	}
	
}

抽象状态(State)

TemperatureState.java

public interface TemperatureState {
	public void showTemperature();
}

具体状态(Concrete State)

LowState.java

public class LowState implements TemperatureState{
	private double n = 0;
	public LowState(double n) {
		if(n<=0) this.n = n;
	}
	@Override
	public void showTemperature() {
		System.out.println("现在温度是"+n+",属于低温度");
	}

}

MiddleState.java

public class MiddleState implements TemperatureState{
	private double n = 15;
	public MiddleState(double n) {
		if(n>0&&n<26)this.n = n;
	}
	@Override
	public void showTemperature() {
		System.out.println("现在温度是"+n+",属于正常温度");
	}

}

HighState.java

public class HighState implements TemperatureState{
	private double n = 39;
	public HighState(double n) {
		if(n>=39)this.n = n;
	}
	@Override
	public void showTemperature() {
		System.out.println("现在的温度是"+n+"属于高温度");
	}

}

测试程序

Example1Test.java

public class Example1Test {
	@Test
	public void testMain() {
		TemperatureState state = new LowState(-12);
		Thermometer thermometer = new Thermometer();
		thermometer.setState(state);
		thermometer.showMsg();
		state = new MiddleState(20);
		thermometer.setState(state);
		thermometer.showMsg();
		state = new HighState(39);
		thermometer.setState(state);
		thermometer.showMsg();
	}
}

四、状态模式的优点。

  1. 使用一个类封装对象的一种状态,很容易增加新的状态。
  2. 在状态模式中,环境(Context)中不必出现大量的条件判断语句。环境(Context)实例所呈现的状态变得更加清晰、容易理解。
  3. 使用状态模式可以让用户程序很方便地切换环境(Context)实例的状态。
  4. 使用状态模式不会让环境(Context)的实例中出现内部状态不一致的情况。
  5. 当状态对象没有实例变量时,环境(Context)的各个实例可以共享一个状态对象。

五、适合状态模式的情景。

  • 一个对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为。
  • 需要编写大量的条件分支语句来决定一个操作的行为,而且这些条件恰好表示对象的一种状态。