java设计模式--状态模式 State

当对象的状态改变时,同时改变其行为。或者说每个状态有着相应的行为。不只是根据状态的,也有根据对象的属性不同,对象的行为也不一样。
"一般的状态判断"和"开关切换状态":
"一般的状态判断"使用if..else if,判断条件和state没有关系,代码如下:

	if(witch=='A'){
		state='B';
	}else if(witch=='B'){
		state='C';
	}else if(witch=='C'){
		state='A';
	}
如果条件成state,就是"开关切换状态",代码如下:
	if(state=='A'){
		state='B';
	}else if(state=='B'){
		state='C';
	}else if(state=='C'){
		state='A';
	}
将 state 的状态从"A"切换到"B",再切换到"C";在切换到"A",好象一个旋转开关,这种状态改变就可以使用 State 模式了。
如果单纯的状态从A->B-C->A 那么也不用state 模式,如果又需要把上面的顺序反转过来,或者要任意的转换,那么最好使用state模式。
状态模式就是把每一个if语句的状态写成一个子类,用子类来代替一个状态,这个子类包含了这个状态的行为和状态之间的转换。

使用satate 模式现上述if..elseif 结构

1.Context
定义客户感兴趣的接口。
维护一个ConcreteState子类的实例,这个实例定义当前状态。被称为状态管理器
2.State
定义一个接口以封装与Context的一个特定状态相关的行为。
3.Statesubclasses  
状态子类实现,每一个状态对应一个子类实现,一个与Context的一个状态相关的行为。

	/**
	 * 状态父类
	 */
	public interface State {
		void change(Context context);
		void doWork();
	}
	public class Context {
		private State state;
		public void setState(State state) {
			this.state = state;
		}
		
		//提供对外接口,把内部转换的工作隐藏
		public State change(){
			state.change(this);
			return state;
		}
	}
状态子类,每一个状态对应一个子类

	public class StateA implements State {
		public void change(Context context) {
			context.setState(new StateB());
		}
		public void doWork() {
			System.out.println("this is state A");
		}
	}
	public class StateB implements State {
		public void change(Context context) {
			context.setState(new StateC());
		}

		public void doWork() {
			System.out.println("this is state B");
		}
	}
	public class StateC implements State {
		public void change(Context context) {
			context.setState(new StateA());
		}
		public void doWork() {
			System.out.println("this is state C");
		}
	}

测试代码:

	public static void main(String[] args) {
		Context  c = new Context();
		c.setState(new StateA());
		//调用“状态管理器”方法后,对应的状态行为也就发生了改变。
		State s = c.change();
		s.doWork();
	}


同样的方式,可以在state中添加任何状态的转变,只要在父类添加方法,在子类中实现并且在状态管理器中添加对应的对外接口就可以了。
上面的例子比较简单的,在实际中处理是比较复杂的。比如工作流就使用了“状态模式”,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等各种状态,使用“状态模式”可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状态的使用者。
状态模式优点:
1、封装转换过程,也就是转换规则。也把相关状态对应的操作放入了子类实现。
2、枚举可能的状态,因此,需要事先确定状态种类。

上例中,如果子类没有做change() 操作,也就是说没有对状态进行转换,就和“策略模式”类似了。这就是二者的区别:“策略模式”不存在“状态”(子类)之间的转换,而“状态模式”可以存在,也可以没有。
二者之前的联系:状态模式和策略模式都是为具有多种可能情形设计的模式,把不同的处理情形抽象为一个相同的接口,符合对扩展开放,对修改封闭的原则。还有就是,策略模式更具有一般性一些,在实践中,可以用策略模式来封装几乎任何类型的规则,只要在分析过程中听到需要在不同实践应用不同的业务规则,就可以考虑使用策略模式处理,在这点上策略模式是包含状态模式的功能的。


状态机:

状态模式可以允许客户端改变状态的转换行为,而状态机则是能够自动改变状态,状态机是一个比较独立的而且复杂的机制,具体可参考一个状态机开源项目。工作流引擎建立在状态机之上的。


你可能感兴趣的:(java设计模式)