Head First 设计模式 12-状态模式
状态模式 允许对象在内部改变状态时改变它的行为,对象看起来好像修改了它的类。
这个模式将状态封装成独立的类,并将动作委托到当前状态的对象,从而让行为随着状态改变而改变。
类图如下图所示。
状态模式 和 策略模式 比较相似。 策略模式 封装的是 算法,状态模式 封装的是 状态。两者的区别在于它们的 “意图” 。
在状态模式中 context 的行为随着状态的改变而改变,但是对于 context 的客户而言,不需要对状态对象有多少的了解,甚至完全不了解。
在策略模式中,则需要客户明确的指定 context 所要组合的策略,但是可以在运行时动态的指定策略,更有弹性。
示例代码
State
csharp
public interface State
{
void handle();
}
1
2
3
4
2
3
4
ConcreteStateA
csharp
public class ConcreteStateA : State
{
Context _context;
public ConcreteStateA(Context context)
{
_context = context;
}
public void handle()
{
Console.WriteLine("StateA handle a request.");
_context.State = _context.StateB;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ConcreteStateB
csharp
public class ConcreteStateB : State
{
private Context _context;
public ConcreteStateB(Context context)
{
_context = context;
}
public void handle()
{
Console.WriteLine("StateB handle a request.");
_context.State = _context.StateA;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Context
csharp
public class Context
{
public ConcreteStateA StateA { get; private set; }
public ConcreteStateB StateB { get; private set; }
public State State { get; set; }
public Context()
{
StateA = new ConcreteStateA(this);
StateB = new ConcreteStateB(this);
State = StateA;
}
public void Request()
{
State.handle();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Client
csharp
var context = new Context();
context.Request();
context.Request();
context.Request();
1
2
3
4
2
3
4