状态模式和策略模式比较相似(类图就完全一样),都是A对象关联B对象,而B是可以更换的,A对象的功能随着B的具体实现的改变而改变。策略模式一般都是B对象在A对象所在的上下文中改变。而状态模式则是在B对象(状态对象)完成一定的操作在B对象内部吧A关联的B的具体实现更换。对于A来说就像是一个封闭的机器,内部实现了一套状态转换的流程而无需外界的干涉。
下面是一个糖果机的例子。
先讨论四种状态,有25分钱,没有25分钱,售出,售罄。然后扩展一个赢家状态。
基本方法有 插入硬币,退出货币,摇动手柄,发出糖果。
糖果机的行为都委托给状态对象去实现。随着状态(对象)的改变糖果机的行为也会改变,也就是说糖果机在不同的状态下表现出不同的行为。
(1?)上面已经提到糖果机内部实现了一套状态转换的流程而无需外界的干涉,那么售罄状态自然也会从某一状态而来,又转向某一状态而去。具体来说就是在售出状态下发放糖果后马上检查还有没有糖果,没有糖果则转到售罄状态,难道这不是售罄状态的所有“来路”吗?在正常状况下自然是这样。我们在初始化糖果机的时候会给出一个初始状态--没有25分钱状态(貌似这样还算比较合理)。但是如果糖果机中一开始就没有糖果那他本身又是一种售罄状态。同时它还没有钱嘛。所以就在插入硬币的时候判断咯,没有糖果就转到售罄然后退出钱。
这里的状态才看起来是有点犯晕。因为这些状态不是互斥的状态。也就是说这里的状态划分不是一种不重不漏的方式。在有钱状态下同时还可以是售罄,没钱也可以是售罄。有25分钱,没有25分钱,表示有没有钱,售罄,表示还有没有糖果,售出表示糖果机的正要进行的动作。表示3类东西的状态竟然放在一起来相互转换 orz,orz。居然还算perfect。懂得模式很重要,发现模式更重要啊。在这个例子中就算想到了状态模式也会由于分析不出正确的状态,而被自己否决吧。完了,感谢CCTV ,感谢BTV ,感谢博客堂,最后最重要的是感谢《head first design pattern》这个例子就是来自与它。