HIT-软件构造-Lab3之State模式

Lab3之状态设计模式

赶在深夜将之前实验三中涉及到的状态模式记录下来,也当做是复习了。

本博客主要从三个角度来考虑。
1.什么是State模式?
2.为什么用State模式?
3.如何使用State模式?

1.State模式简要介绍

简要的介绍来说State模式就是:不同的状态,不同的行为。
也就是允许一个对象,当其内部状态改变时,改变其行为的方式。

在这里插入图片描述
如上图所示,航班在Wait状态下,可以给其分配飞机资源,指定该航班当前有哪些飞机。
当航班在Allocate状态下,表示当前航班有飞机,那么可以起飞,取消等等。
当航班在Run状态下,表示当前航班的飞机已经起飞,那么只能进行降落。

这里采用的就是不同状态下不同的方法,需要注意的是,每个状态下的方法是特有的,例如:Wait状态下不能够起飞,因为没有被分配飞机。

2.使用State模式的好处

在实际编程中,我们会经常使用if…else等语句进行条件的判断,不同的条件下执行不同的语句,这些语句使用起来很是方便。
但是,如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.

必须要使用State模式吗?答案是否定的,但是回到了代码的可维护性、可扩展性、可复用性等诸多层面考虑。就拿实验3的内容来举例。
我们针对计划项设置了不同的状态,不论那个计划项都有下面几种状态:Waiting,Allocated,Running,Ended,Cancelled
这五种状态是计划项共有的,暂且不考虑特殊的状态,我们在实验3中要实现3种计划项。每种计划项至少包含上面五种状态,如果不采用State模式,我们就得采用if…else语句,或者switch语句,进行状态判断,语句执行。这样会使用很多的代码。
针对不同的计划项,我们还要拷贝代码,让三种计划项都有状态的操作,这无疑造成了代码复杂,重复,又造成了代码的重复。
如果我们想要对某个状态的操作进行改动,就需要对所有计划项的代码都进行改动,这样代码可复用性,可维护性都不好。

针对这种情况,我们就可以采用状态设计模式,定义不同的状态子类,在每个子类下定义相关的操作。
同时,定义一个状态转换的开关,帮助我们进行状态的切换操作。

3.State模式的具体应用方法

下面主要介绍下本次实验的State模式的应用设计

public class EntryState {
	private State state = null;

	// Abstraction function:
	// state 代表计划项当前的状态
	// 需要满足状态转换图

	// Representation invariant:
	// 初始化为WAITING状态
	// 每个State转换时需满足状态关系图

	// Safety from rep exposure:
	// 所有数据都是private且final
	// 无表示泄露

	// TODO checkrep
	public boolean checkrep() {
		if (this.state instanceof WaitingState || this.state instanceof RunningState
				|| this.state instanceof BlockedState || this.state instanceof CancelledState
				|| this.state instanceof EndedState || this.state instanceof AllocatedState)
			return true;
		else
			return false;
	}

	/**
	 * Constructor
	 * 
	 * @param s String,the state's name and must be waiting
	 */
	public EntryState(String s) {
		this.state = new WaitingState();
		if (!checkrep())
			assert false;
	}
/**
 * set the entry's state
 * @param state
 */
	public void setState(State state) {
		this.state = state;
		if (!checkrep())
			assert false;
	}
	/**
	 * Observer,get the entry's state 
	 * @return State
	 */

	public State getState() {
		return this.state;
	}
/**
 * Change the state to allocated
 * @param type is the entry's type
 */
	public void allocat(String type) {
		state.Allocat(this, type);
	}
	/**
	 * Change the state to running
	 * @param type is the entry's type
	 */
	public void run(String type) {
		state.Run(this, type);
	}
	/**
	 * Change the state to blocked
	 * @param type is the entry's type
	 */
	public void block(String type) {

		state.Block(this, type);
	}
	/**
	 * Change the state to cancelled
	 * @param type is the entry's type
	 */
	public void cancel(String type) {
		state.Cancel(this, type);
	}
	/**
	 * Change the state to ended
	 * @param type is the entry's type
	 */
	public void end(String type) {
		state.End(this, type);
	}
	
   @Override
	public boolean equals(Object obj) {
	   if(obj instanceof EntryState)
	   {EntryState e=(EntryState) obj;
		if (e.getState().getState().equals(state.getState()))
			return true;}
		return false;
	}
}

EntryState类实际上就是切换的开关,State类就是切换的状态的子类,在每个State类中都有不同的操作。
在EntryState类中,提供了Set方法,用来切换State类,达到状态的切换。

总结

State模式采用简洁的代码通过接口,抽象类等方式,抽象状态为类,然后通过一个状态切换开关去切换状态,执行不同的操作。对于每种状态又委托控制状态的逻辑进行修改和操作,实现起来非常简洁。
采用这个模式,就需要编程人员提取出不同状态,以及同意状态下的相同操作(共性),让问题简单化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值