用途
透過改變狀態來改變行為,讓每個狀態行為獨立易於添加、修改
classDiagram
ConcreteStateA ..|> IState
ConcreteStateB ..|> IState
IState --o Context
Client ..> Context
note for Client "Create context then use request"
namespace State {
class IState{
<<Interface>>
+HandleRequest(Context)
}
class ConcreteStateA{
+HandleRequest(Context)
}
class ConcreteStateB{
+HandleRequest(Context)
}
class Context{
-State state
+ChangeState(IState)
+Request()
}
}
class Client{
+Operation()
}
例子
當談到狀態模式(State Pattern)時,我們可以使用簽核的情境來解釋
在許多組織或系統中,文件或任務需要經過一系列的簽核程序
每個簽核階段都有不同的狀態和操作
這個情境可以很好地展示狀態模式的應用。
State
1
2
3
4
| public interface State
{
void HandleRequest(Context context);
}
|
ConcreteState
1
2
3
4
5
6
7
8
9
| public class ConcreteStateA : State
{
public void HandleRequest(Context context)
{
Console.WriteLine("HandleRequest in ConcreteStateA");
// 改變狀態為ConcreteStateB
context.ChangeState(new ConcreteStateB());
}
}
|
1
2
3
4
5
6
7
8
9
| public class ConcreteStateB : State
{
public void HandleRequest(Context context)
{
Console.WriteLine("HandleRequest in ConcreteStateB");
// 改變狀態為ConcreteStateA
context.ChangeState(new ConcreteStateA());
}
}
|
Context
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| public class Context
{
private State currentState;
public Context()
{
// 初始狀態為ConcreteStateA
currentState = new ConcreteStateA();
}
public void ChangeState(State state)
{
currentState = state;
}
public void Request()
{
// 呼叫當前狀態的操作
currentState.HandleRequest(this);
}
}
|
Client
1
2
3
4
5
| // 使用範例
Context context = new Context();
context.Request(); // 輸出: HandleRequest in ConcreteStateA
context.Request(); // 輸出: HandleRequest in ConcreteStateB
context.Request(); // 輸出: HandleRequest in ConcreteStateA
|
延伸