用State模式减少if..elseif语句

   我们在写程序的过程中会遇到很多的逻辑判断,一般都是用if ..else、if..else if、swith(..) case等来做判断,然后根据结果做一下分支处理,这样写虽然方便,但会增加以后的维护难度,假如有上百个if ..else if判断,估计后期维护的人看到代码头都大了。像这种情况可以用state模式来解决。

  State模式是行为模式之一。当某个对象的内部状态(通俗的说,成员变量)发生改变,它的行为也会发生改变。

  状态模式的角色:
抽象状态、具体状态(一种或多个状态,每种状态对应不同的行力),环境(context)角色(就是对象,包括当前对象状态、改变状态的方法和状态行为方法)

  为了帮助理解,举例说明:

  一个画图程序,有一个控制面板,上面罗列了各种画图工具以及其它颜色选择,滴管等工具,当用户选择或改变了画图工具时,就可以使用各种不同的工具进行画图或其他操作了。
我们把这个过程用另外一种方法再描述一下:
- 用户选择画图工具就是一个画笔状态的改变。
- 每个工具能画的图形可能完全不一样,也就是说它们的行为各不一样。
- 改变了画图工具,在画布上画出的图形当然也不一样了,换句话说,画笔状态的改变导致行为的不一样。
 再举个例子,100米短跑远动员。他有三种状态,生病状态,正常状态,兴奋状态。那么状态决定这个运动员的行为,生病状态跑的速度慢,兴奋状态跑的速度快。我们以运动员程序为例,如果不用设计模式的话,我们可能会这写

package com.bill99.pattern;

/**
 *<p>title: 一般运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class Gamer {
	private final int NORMAL_STATE = 0; //正常状态
	private final int MALUM_STATE =1;   //生病状态
	private final int EXCITED_STATE =2; //兴奋状态
	private int state = 0;
	public void setState(int state){
		this.state = state;
	}
	public void run() {
		if(state == NORMAL_STATE) {       //正常状态下跑
			System.out.println("100米,跑完共用时15秒!");
		} else if(state == MALUM_STATE) { //生病状态下跑
			System.out.println("100米,跑完共用时20秒!");
		} else if(state == EXCITED_STATE) {//兴奋状态下跑
			System.out.println("100米,跑完共用时10秒!");
		} else {
			System.out.println("未知的状态");
		}
	}
}

 

如果以后维护的话,要再加一个超级兴奋的状态,得要改原来的源代码,添加一个代表超级兴奋的成员变量,再改if..else if判断,这样做不符合OO设计原则,实现不了程序的松耦合。

下面用状态模式来实现

package com.bill99.pattern.state;

/**
 *<p>title:状态接口 </p>
 *<p>Description:状态接口,每一个状态都要实现此接口 </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public interface IState {
	/**
	 * 起跑
	 */
	public void doRun();
}

 

package com.bill99.pattern.state;

/**
 *<p>title: 兴奋状态运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class ExcitedState implements IState {
	public void doRun() {
		System.out.println("100米,跑完共用时10钞!");
	}
}

 

package com.bill99.pattern.state;

/**
 *<p>title:生病状态运动员 </p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class MalumState implements IState {

	public void doRun() {
		System.out.println("100米,跑完共用时20秒!");
	}
}

 

package com.bill99.pattern.state;

/**
 *<p>title:正常状态运动员 </p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class NormalState implements IState {

	public void doRun() {
		System.out.println("100米,跑完共用时15秒!");
	}
}

 构建一个场景,运动员类,该运动员类包括表示当前对象状态的成员变量,改变当前状态的方法,和状态行为方法

package com.bill99.pattern.state;

/**
 *<p>title: 采用状态模式的运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class Gamer {
	//当前状态
	private IState state = new NormalState();
	//改变状态的方法
	public void setState(IState state){
		this.state = state;
	}
	//状态行为方法,同上面的Gamer 类相比这里没有if..else if判断
	public void run() {
		state.doRun();
	}
}

 测试类

package com.bill99.pattern.state;

/**
 *<p>title: 测试类</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <[email protected]>
 */
public class StateTest {
	public static void main(String[] args) {
		//没有使用状态设计模式
		com.bill99.pattern.Gamer game = new com.bill99.pattern.Gamer();
		game.setState(0);
		game.run();
		game.setState(1);
		game.run();
		game.setState(2);
		game.run();
		System.out.println("---------------------");
		//使用状态设计模式
		//正常状态下跑 
		Gamer gamer = new Gamer();
		gamer.run(); 
		//生病状态下跑
		gamer.setState(new MalumState());
		gamer.run();
		//兴奋状态下跑
		gamer.setState(new ExcitedState());
		gamer.run();
	}
}

 

运行结果:

100米,跑完共用时15秒!
100米,跑完共用时20秒!
100米,跑完共用时10秒!
---------------------
100米,跑完共用时15秒!
100米,跑完共用时20秒!
100米,跑完共用时10钞!

 

假如我们再扩展一个超级兴奋的状态SuperExcitedState,只需实现IState接口,定义好该状态的行为,调用如下

gamer.setState(new  SuperExcitedState());

gamer.run();

而不用改原有代码,提高程序的松耦合。

你可能感兴趣的:(设计模式,C++,c,C#,OO)