机房收费系统中要完成上机功能,我们需要先判断1.卡号是否存在?2.卡号是否已在线 3.卡内余额是否充足?而这每一种判断,我们在实现的时候,都需要做出相应的处理。在做个人版的时候,都是If….else或switch case 语句来做一系列的判断。所以针对这个情况,这次我们就在这个功能添加状态模式。
那么什么是状态模式呢? 它是如何在某一种状态下表现出不同的行为呢?它的主要好处是什么呢?
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来似乎是改变了其类。 如图:
通常,一个对象的行为主要取决于一个或多个动态变化的属性(也就是成员变量),这样的属性就叫做状态。具体状态的行为是什么?那就看这个属性的具体变化是什么?
结合图可知:状态模式主要是将状态抽离出来(State),分离出个个具体的状态子类(ConcreteState),并且让Context切换具体的状态,从而具备不同的行为。 (Context在不同状态下具有不同的行为)
对状态模式的理解,是在一次次的讨论中逐步成熟起来的。在设计我们的上机功能的状态模式中,经历过了三个版本:
第一版本:
这个版本称不上是状态模式,看上面的红色部分,就可以看出在实现的过程中,流程是如何。
错误:
第一,内部子状态之间联系过于紧密。用来决定不同状态的不同行为应该是由OnlineBLL 来决定,而不是具体的子类来决定。这样这个状态模式就没有存在的意义了。
第二就是参数错误!!!执行方法的参数个数不一致!
第三,无构造函数
如果不经过讨论,都没有意识到在最后AddOnlineRecord中的OnlineRecordEnity的参数是无法传递过来。
第二个版本:
第三个版本:
此时:
1.CardNoExitState、IsOnline等行为不直接写在OnlineBLL 类中。
2.CardNoExitState、IsOnline等行为被抽象成CardStateBLL,并且OnlineBLL中含有对每个CardState的引 用,通过SetCurrentState来设置当前的状态值。
3.调用OnlineBLL.Online()方法,OnlineBLL会根据当前的状态做出适当的行为。
4.增加一个状态,只需要增加一个CardState的实现即可。
状态模式的一个大的好处,将具体的状态判断转移到具体的子类当中,再重新定义一个类,来切换不同的状态获取不同的行为。所以通过定义新的子类可以很容易地增加新的状态和转换。
设计跟实现之间有很大的区别,并且这个两个由不同的人来完成时。存在争议是必不可少的。而且每个人对同一件事物的看法不一样。所以,在出现争议的时候,先听听别人的看法,如果他的看法此时不能够说服你,你还是认为自己的理解是正确的,那就努力的去把对方给说服,如果自己还是不行,可以向经验丰富的人请假。通过这个不断的讨论,探究的过程,你也会对这个知识不断的深化理解。而且,当你在向对方表达你的想法的时候,那也是你对知识 的一种梳理。
所以,在合作中,我认为最重要的还是讨论跟交流。