13.3 如何封装变化

    从图13-1我们知道,在不同颜色状态下push操作和pull操作是不一样的。譬如,当前状态是红色,push操作会使状态变成绿色;如果状态是绿色,则会变成蓝色。不同的状态关联不同的行为,这就是该场景的变化方式。为此,我们抽象出一个状态的接口,它定义了与状态相关的方法,于是,具体的状态就可以封装与之相关的行为了。

    现在就让我们来构造它们:State是状态接口,含有push(PaintBoard paintBoard)和pull(PaintBoard paintBoard)两个方法;PaintBoard类包含push()和pull()两个方法,它把这两个操作委托给当前状态完成。

    UML静态类图如图13-2所示。

    figure_0196_0202

    图13-2

    来看看PaintBoard类的代码,大致如下。

    figure_0196_0203

    每个具体状态的push操作和pull操作都会回调PaintBoard的方法setState(State state)来设置PaintBoard的新状态。State接口和RedState实现类的代码如下所示。

    figure_0197_0205

    figure_0198_0206

    其他具体状态类与RedState类相似,具体代码我们就不再赘述,请参见示例代码。

    下一步我们创建测试代码,如下所示。

    figure_0198_0207

    figure_0199_0208

    最后看看测试效果,如下所示。

    figure_0199_0209

    figure_0200_0210

    当前状态代理了PaintBoard的push和pull操作,这样,PaintBoard类的代码里再也找不到“丑陋”的条件分支语句,代码也就更加容易阅读。如果需要添加更多的状态,只要添加新的State接口实现即可,符合OCP原则。