都说状态模式和策略模式很像,它们的 UML 类图一样。这也说明,单纯从代码角度来讲,它们的本质一样,其实都是多态的应用。但它们实际所代表的的事物特征是有本质区别的,选择哪个设计模式,代表了你看待业务场景的角度。从合理角度地对业务进程抽象,选择恰当的设计模式,才能让代码有更好的结构。
这篇文章重点说说我对状态模式和策略模式区别的理解,以及如何选择。
一、策略模式
关于策略模式,我之前写过一篇笔记,不过是 C# 写的。策略模式解决了代码逻辑分支较多,对不同的分支,采取不同措施的问题。不熟悉策略模式的,也可以上集回顾:
二、状态模式
状态模式中的行为是由状态来决定的,在状态模式(State Pattern)中,类的行为是基于它的状态改变的。我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。这种类型的设计模式也属于行为型模式。
状态模式简介
意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
何时使用:代码中包含大量与对象状态有关的条件语句。
如何解决:将各种具体的状态类抽象出来。
关键代码:状态模式的接口中通常有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和策略模式一样,也可以用于消除 if...else 等条件选择语句。
状态模式的模型代码
- 状态的抽象,定一个状态接口,声明不同状态下所需实现的方法:
public interface State { void function1(); void function2(); } - 具体的状态类,定义不同的状态类,实现状态抽象接口:
public class StateA implements State { @Override public void function1() { System.out.println("invoke StateA function1 ..."); } @Override public void function2() { System.out.println("invoke StateA function2 ..."); } }public class StateB implements State { @Override public void function1() { System.out.println("invoke StateB function1 ..."); } @Override public void function2() { System.out.println("invoke StateB function2 ..."); } }- 维护状态的上下文环境,Context 类:
public class Context { private State state; public Context() { } public Context(State originalState) { this.state = originalState; } public
