java设计模式:状态模式

1.状态模式

状态模式(state),又称状态对象模式,是对象的行为模式

状态模式允许对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。

2.状态模式的结构

状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。示意图如下:



状态模式参与角色:

  • 抽象状态(State)角色:定义接口,用来封装环境(Context)对象一个特定状态所对应的行为。
  • 具体状态(ConcreteState):具体状态类有多个,分别实现了环境的一个状态对应的行文。
  • 环境角色(Context):定义客户端感兴趣的接口(request),并且保留一个具体状态类的实例。这个实例给出环境对象的现有状态。

可以看出:客户端通过request请求Context环境类,而环境类通过state实例的处理,改变Context的呈现状态。

3.状态模式的效果

  • 状态模式为系统的每一个状态都创立一个具体状态类。当系统的状态变化时,系统改变对应的状态类。而且一个特定状态的所有行为都被封装到一个特定的对象中,使得行为的定义局域化。如果有新的状态添加,不需要修改客户端和context,只需要添加一个新的状态类。
  • 不必采用过程性的处理方式,使用很长的条件转移语句。
  • 使系统状态变化变得很明显,不用使用一些变量来标识。
  • 可以在系统的不同部分使用相同的一些状态类的对象。
  • 状态模式的缺点是会造成大量的晓得状态类;优点是使程序避免大量的条件转移语句,更易维护。

4.一个实现:电梯系统

一个电梯,基本会有:开、关、正在升降和停止4个状态,每个状态下行为不一样,很适合使用状态模式。使用状态模式后的类图如下:


LiftState(抽象状态)
package com.patterns.state;

/**
 * 抽象状态
 * @author Administrator
 *
 */
public abstract class LiftState {

  protected Context context;

  
  
  public abstract void open();

  public abstract void close();

  public abstract void run();

  public abstract void stop();

}

具体状态类:

ClosingState

package com.patterns.state;

/**
 * 关闭状态的具体状态类,可以执行开,关和停止请求
 * @author Administrator
 *
 */
public class ClosingState extends LiftState {

	@Override
	public void open() {		
		//状态改变
		this.context.setLiftState(Context.openningState);
		//执行动作
		this.context.open();
	}

	@Override
	public void close() {		
		System.out.println("lift is closing");
	}

	@Override
	public void run() {		
		this.context.setLiftState(Context.runningState);
		this.context.run();
	}

	@Override
	public void stop() {		
		this.context.setLiftState(Context.stoppingState);
		this.context.stop();
	}
}

OpenningState

package com.patterns.state;

/**
 * 正在开门状态,只能执行开门请求
 * @author Administrator
 *
 */
public class OpenningState extends LiftState {

	@Override
	public void open() {
		System.out.println("lift is openning .");
	}

	@Override
	public void close() {
		//状态改变
		this.context.setLiftState(Context.ClosingState);
		this.context.close();
	}

	@Override
	public void run() {		
		
	}

	@Override
	public void stop() {		
		
	}
}

RunningState

package com.patterns.state;

/**
 * 正在运行状态,只会执行停止动作
 * @author Administrator
 *
 */
public class RunningState extends LiftState {

	@Override
	public void open() {		
		
	}

	@Override
	public void close() {
		
		
	}

	@Override
	public void run() {
		
		System.out.println("lift is running.");
	}

	@Override
	public void stop() {
		this.context.setLiftState(Context.stoppingState);
		this.context.stop();
	}
}

StoppingState

package com.patterns.state;

/**
 * 停止状态,可以执行开门和运行请求
 * @author Administrator
 *
 */
public class StoppingState extends LiftState {

	@Override
	public void open() {
		this.context.setLiftState(Context.openningState);
		this.context.open();
		
	}

	@Override
	public void close() {
		
		
	}

	@Override
	public void run() {
		this.context.setLiftState(Context.runningState);
		this.context.run();
	}

	@Override
	public void stop() {		
		System.out.println("lift is stopping");
	}
}

Context(环境类)

package com.patterns.state;


/**
 * 环境类
 * @author Administrator
 *
 */
public class Context {
	/**
	 * 定义一些共享的状态类,可重复使用
	 */
	public static LiftState openningState = new OpenningState();
	public static LiftState ClosingState = new ClosingState();
	public static LiftState runningState = new RunningState();
	public static LiftState stoppingState = new StoppingState();
	
	
	protected LiftState state;

	public LiftState getLiftState() {
		return state;
	}

	//设置状态
	public void setLiftState(LiftState state) {
		this.state = state;
		//把环境告诉状态
		state.context = this;
	}

	//下面的函数,是把客户端的请求委托给状态类来执行
	
	public void open() {
		state.open();
	}

	public void close() {
		state.close();
	}

	public void run() {
		state.run();
	}

	public void stop() {
		state.stop();
	}

}

Client(测试类)

package com.patterns.state;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//创建环境
		Context context = new Context();
		//初始化一个状态
		context.setLiftState(Context.stoppingState);
		
		//请求测试
		context.open();
		context.close();
		context.run();
		context.stop();

	}

}

输出:
lift is openning .
lift is closing
lift is running.
lift is stopping



5.状态模式和策略模式的区别

策略模式和状态模式的结构相同,所以很容易混淆。它们主要区别在于:
  • 策略模式中一旦环境类选择了一个具体策略类,在整个环境类的生命周期中策略类是不会改变的。而状态模式的环境类中的状态有一个明显的状态转移。
  • 策略模式的环境类自己选择具体策略类,而状态模式的环境类是被外在原因放进一个状态中。
  • 策略模式的环境类并不明显告诉客户端自己所选的策略,而状态模式的状态是显示告诉客户端的。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值