状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
1. 策略模式和状态模式是双胞胎,它们有相同的类图,但是它们的意图不同。策略模式是围绕可以互换的算法来成功创建业务的,然而状态模式是通过改变对象内部的状态来帮助对象控制自己的行为.
2. Context将与状态相关的操作委托给当前的Concrete State对象处理。
3. Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
4. Context或Concrete State类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。也就是说可以在State中保存对Concrete State的引用,在必要时设置具体的状态,做到状态的转换。
5. 一般来讲,当状态转换是固定的时候,状态转换就适合放在Context中。然而,当转换是更动态的时候,通常会放到具体的状态类中进行。(具体状态类持有Context的引用,实现状态的转换)
状态模式和策略模式的最大区别在于它有状态间的切换,一个状态完了,就要切换到它下一个状态。
举一个例子:我们给一部手机打电话,就可能出现这几种情况:用户开机,用户关机,用户欠费停机,用户消户等。 所以当我们拨打这个号码的时候:系统就要判断,该用户是否在开机且不忙状态,又或者是关机,欠费等状态。但不管是那种状态我们都应给出对应的处理操作。下面我们用代码来模拟一下这个过程。
package com.qinsoft.design; /** * 状态模式:行为型 */ interface IState { //打电话 void call(); //通话计时 void countTimes(); // 其他操作。 } /** * 电话等待状态 */ class WaitState implements IState{ @Override public void call() { System.out.println("等待状态:用户正在通话,请稍后再拨"); } @Override public void countTimes() { System.out.println("等待状态:电话不在连接状态,不能计时"); } } /** * 电话接通状态 */ class ConnectState implements IState{ @Override public void call() { System.out.println("接通状态:连接成功,可以通话"); } @Override public void countTimes() { System.out.println("接通状态:计时处理。。。"); } } class Context { public static IState wait = new WaitState(); public static IState connect = new ConnectState(); private static IState state = connect; public void call() { state.call(); } public void countTimes() { state.countTimes(); } public void changeState(IState concreteState) { state = concreteState; } } public class State { public static void main(String[] args) { Context context = new Context(); //接通状态下 context.call(); context.countTimes(); //改变状态 context.changeState(Context.wait); //等待状态下 context.call(); context.countTimes(); } }