行为型(二)—状态模式

1、介绍

状态模式中的行为是由状态决定的,不同的状态有不同的行为。状态模式与策略模式的结构一样的,但它们的目的和本质不同,状态模式的行为是平行的,不可替换的,而策略模式的行为是对立的,可替换的。

2、定义

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

当一个对象的内在类改变时允许改变其行为,这对象看起来像是改变了其类。

3、使用场景

  1.  对象的行为依赖它所处的状态,并且在运行是根据状态改变它的行为
  2. 代码中含有大量的跟状态有关的条件语句。

4、UML类图


角色说明:

  1. Context:屏蔽高层模块对行为的直接访问,它持有一个State类的引用
  2. State:对每个行为的抽象
  3. ConcreteStateA、ConcreteStateB:具体的行为类。

5、示例

以遥控器为例来说明状态模式的实现。首先状态模式分为开机和关机状态,在开启状态下,可以进行切换频道、关机操作,但重复开机按键无效;在关机状态下,切换频道和重复关机无效,只能先进行开机操作。

首先看一下普通的实现方式。

/**
 * 电视控制类,含有开机、关机、下一个频道、上一个频道的功能
 * @author Administrator
 *
 */
public class TVController1 {
	private final static int POWER_ON = 1;
	private final static int POWER_OFF = 2;
	private int mState = POWER_OFF;
    public void powerOn(){
		if (mState == POWER_OFF) {
			System.out.println("开机了");
		}
		mState = POWER_ON;
	}
    public void powerOFF(){
    	if (mState == POWER_ON) {
			System.out.println("关机了");
		}
		mState = POWER_OFF;
	}
	public void nextChannel(){
		if (mState == POWER_ON) {
			System.out.println("下一个频道");
		}else {
			System.out.println("抱歉,没有开机");
		}
		
	}
    public void preChannel(){
    	if (mState == POWER_ON) {
			System.out.println("上一个频道");
		}else {
			System.out.println("抱歉,没有开机");
		}
	} 
}

在TVController类中,同名mState存储电视状态,在进行频道切换时,必须通过if-else进行条件判断进行操作,代码重复,相对较为混乱。

接下来,通过状态模式来实现。

/**
 * 状态接口
 * @author Administrator
 *
 */
public interface TVState {
	public void nextChannel();
	public void preChannel();
}
/**
 * 具体状态实现类,开机状态
 * @author Administrator
 *
 */
public class PowerOnState implements TVState {

	@Override
	public void nextChannel() {
		System.out.println("下一个频道");
	}

	@Override
	public void preChannel() {
		System.out.println("上一个频道");
	}

}
/**
 * 具体状态实现,关机状态
 */
public class PowerOffState implements TVState{
	@Override
	public void nextChannel() {
		System.out.println("抱歉,请先开机");
	}

	@Override
	public void preChannel() {
		System.out.println("抱歉,请先开机");
	}
}
/**
 * 电源操作接口
 */
public interface PowerController {
	public void powerOn();
	public void powerOff();
}
public class TVController implements PowerController{
	private TVState mState = null;

	public void setState(TVState state) {
		this.mState = state;
	}
	
	public void nextChannel(){
		mState.nextChannel();
	}
	
	public void preChannel() {
		mState.preChannel();
	}

	@Override
	public void powerOn() {
		setState(new PowerOnState());
		System.out.println("开机了");
	}

	@Override
	public void powerOff() {
		setState(new PowerOffState());
		System.out.println("关机了");
	}	
}
/**
 * 客户端调用
 */
public class Client {
	public static void main(String[] args) {
		TVController controller = new TVController();
		controller.powerOn();
		controller.nextChannel();
		controller.preChannel();
		
		controller.powerOff();
		controller.nextChannel();
		controller.preChannel();
	}
}

输出结果如下:

开机了
下一个频道
上一个频道
关机了
抱歉,请先开机
抱歉,请先开机

6、总结

优点:State模式将所有与一个状态对象有关的行为组织成一个接口类,统一管理,结构清晰,避免代码臃肿,同时也保证了可扩展性和可维护性

缺点:子类太多,不易管理

猜你喜欢

转载自blog.csdn.net/zcjxaiofeizhu/article/details/80721049