设计模式之状态模式

状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类,属于行为型模式。

状态模式描述了对象状态的变化,以及对象如何在不同状态下表现出不同的行为。通过引入了一个抽象的状态类来表示状态,每一种具体状态类都继承此类,在不同的具体状态类中实现不同状态的行为,且包括状态之间的转换。

组成

状态模式由抽象状态 State 、具体状态 ConcreteState 和上下文 Context 组成。

其中 State 定义行为接口;ConcreteState 实现 State 中定义的接口,将不同状态下的行为单独提取出来进行封装;Context 持有 State ,行为随 State 的改变而改变。

优点

行为封装在状态中,修改对象状态即可改变对象的行为。

不同状态的行为被分割开,方便增加新的状态和行为。

状态对象封装了状态的转换规则,从而减少巨大的条件语句块。

多个上下文可以共享状态对象,减少系统中对象的个数。

缺点

结构与实现都较为复杂,使用不当会导致程序结构和代码混乱。

会增加系统中类和对象的个数。

对开闭原则的支持不够好。(对于可以切换状态的状态模式,增加新的状态类需要修改状态转换逻辑,否则无法切换到新增状态;修改状态类的行为也需修改对应类的源代码。)

使用场景

对象的行为随状态改变而改变、状态变化依靠大量的分支判断语句实现时,可以使用状态模式。

设计原则

遵循单一职责原则、依赖倒置原则和开闭原则。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public abstract class State {
public abstract void work(Context context);
}

public class ConcreteStateA extends State {

@Override
public void work(Context context) {
System.out.println("WORKING IN " + context.getState().getClass().getSimpleName());
context.setState(new ConcreteStateB());
}
}

public class ConcreteStateB extends State {

@Override
public void work(Context context) {
System.out.println("WORKING IN " + context.getState().getClass().getSimpleName());
context.setState(new ConcreteStateA());
}
}

public class Context {

private State state;

public Context(State state) {
this.state = state;
}

public void setState(State state) {
this.state = state;
}

public State getState() {
return state;
}

public void request() {
this.state.work(this);
}
}

public class Client {
public static void main(String[] args) {
Context context = new Context(new ConcreteStateA());
context.request();
context.request();
}
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • © 2016-2020 姜越

谢谢老板

支付宝
微信