◎筱米加步枪◎.Blog

Happy coding

状态模式

筱米加步枪 posted @ 2010年3月25日 02:49 in [ 设计模式 ] with tags 设计模式 状态模式 , 1921 阅读

定义摘自《head first》中:

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

对于使用者来说看起来好像是能够修改自己的类,实际上是委托状态对象来改变相关操作。

状态模式类图如下(截图于《head first》):

对于状态模式,我自己举了例子:描述一个人经过外界时间的影响,心情状态会有不同的变化。

例如:一个人捡到钱了,当然是很高兴,钱丢了当然就不高兴也就是悲伤了,当丢的钱又捡回来了,于是就从悲伤变成高兴了。

看下面状态图:

使用状态模式实现,代码如下:

1.状态接口

/**
 * 状态接口
 * 
 * @author ChenST
 *
 * @create 2010-3-25
 */
public abstract class State {
	
	/** 状态名 */
	private String name;
	
	/**
	 * 捡到钱了
	 */
	public abstract void pickMoney();
	
	/**
	 * 丢钱了
	 */
	public abstract void loseMoney();
	
	/**
	 * 钱捡回来了
	 */
	public abstract void backMoney();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

2.正常状态

/**
 * 正常状态
 * 
 * @author Administrator
 *
 * @create 2010-3-25
 */
public class NormalState extends State {

	/** 该状态所发生的实体 */
	private Person person;
	
	public NormalState(Person person) {
		this.person=person;
		this.setName("正常");
	}
	
	public void loseMoney() {
		//丢钱了,很悲伤,状态转变
		System.out.println("钱丢啦!");
		person.setCurrent(person.getSad());
	}

	public void pickMoney() {
		System.out.println("捡到钱了!");
		person.setCurrent(person.getHappy());
	}

	public void backMoney() {
		//无状态改变
	}
}

3.高兴状态

/**
 * 高兴的状态
 * 
 * @author ChenST
 *
 * @create 2010-3-25
 */
public class HappyState extends State {

	/** 该状态所发生的实体 */
	private Person person;
	
	public HappyState(Person person) {
		this.person=person;
		this.setName("高兴");
	}
	
	public void backMoney() {
		//无任何状态改变
	}

	public void loseMoney() {
		//无任何状态改变
	}

	public void pickMoney() {
		//无任何状态改变
	}
}

4.悲伤状态

/**
 * 悲伤状态
 * 
 * @author ChenST
 *
 * @create 2010-3-25
 */
public class SadState extends State {

	/** 该状态所发生的实体 */
	private Person person;
	
	public SadState(Person person) {
		this.person=person;
		this.setName("悲伤");
	}
	
	public void backMoney() {
		//丢失的钱失而复得,很高兴
		System.out.println("捡回来了,原来丢在这儿了");
		person.setCurrent(person.getHappy());
	}

	public void loseMoney() {
		//无状态改变
	}

	public void pickMoney() {
		//无状态改变
	}
}

5.人类,状态存在的实体

/**
 * 一个人的类
 * 
 * @author ChenST
 *
 * @create 2010-3-25
 */
public class Person extends State{

	/** 高兴的状态 */
	private State happy;
	
	/** 悲伤的状态 */
	private State sad;
	
	/** 正常的状态 */
	private State normal;
	
	/** 当前的状态 */
	private State current;
	
	public Person(){
		this.happy=new HappyState(this);
		this.sad=new SadState(this);
		this.normal=new NormalState(this);
		//当前状态为正常状态
		this.current=this.normal;
	}
	
	/**
	 * 显示打印当前状态
	 */
	public void showCurrentState(){
		System.out.println(current.getName());
	}
	
	/**
	 * 重新设置状态,回复默认状态
	 */
	public void resetState(){
		this.current=this.normal;
	}
	
	//
	//委托给状态对象去执行操作
	//
	public void backMoney() {
		current.backMoney();
	}

	public void loseMoney() {
		current.loseMoney();
	}

	public void pickMoney() {
		current.pickMoney();
	}

	public State getCurrent() {
		return current;
	}

	public void setCurrent(State current) {
		this.current = current;
	}

	public State getHappy() {
		return happy;
	}

	public void setHappy(State happy) {
		this.happy = happy;
	}

	public State getNormal() {
		return normal;
	}

	public void setNormal(State normal) {
		this.normal = normal;
	}

	public State getSad() {
		return sad;
	}

	public void setSad(State sad) {
		this.sad = sad;
	}
}

6.测试类

/**
 * 测试类
 * 
 * @author ChenST
 *
 * @create 2010-3-25
 */
public class Test {
	
	public static void main(String[] args) {
		//今天詹姆斯出去买东西
		Person james=new Person();
		james.pickMoney();		 //今天运气好,捡到钱了
		james.showCurrentState();//查看下詹姆斯的心情
		james.resetState();		 //于是不买东西了回家了.(恢复默认状态)
		james.showCurrentState();//查看下詹姆斯的心情
		
		//第二天詹姆斯又出去买东西
		james.loseMoney();		 //今天运气不好,丢钱了
		james.showCurrentState();//查看下詹姆斯的心情
		james.backMoney();		 //今天运气还不算很差,钱捡回来了。
		james.showCurrentState();//查看下詹姆斯的心情
	}
}

7.运行结果

捡到钱了!
高兴
正常
钱丢啦!
悲伤
捡回来了,原来丢在这儿了
高兴

OK~~完毕~可以看到,如果对状态的增加或者修改,或者对行为的增加或修改,都可以很好的扩展和维护。只要在人的类里面增加相应的状态和方法即可改变,而不需要改变整体结构,用增加类来代替if 的条件判断。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter