狀態模式(state):允許一個對象在其狀態改變時,改變它的行爲。看起來對象似乎修改了它的類。別名:狀態對象(Objects for State)。
2.圖示:
3.使用場景
1). 一個對象的行爲取決於它的狀態,並且他必須在運行時刻根據狀態改變它的行爲。
2 ).一個操作中含有龐大的多分枝的條件語句,並且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常,有多個操作包含這一相同的條件結構。
State模式將每一個條件分支放入一個獨立的類中。這是得你可以根據對象自身的情況將對象的狀態作爲一個對象,這一對象可以不依賴於其他對象而獨立變化。
爲了幫助理解,我們舉例來說明:
一個加密的程序,有一個加密的控制中心,上面羅列了各種加密的方法可以供選擇,當用戶選擇或者改變了加密方式時,就可以使用不同的加密方式來進行加密
4。代碼示例
//加密選擇事件處理方法
public void encryptControl(String state) {
//根據不同的加密方式來進行數據的加密
if (state == MD5) {
MD5Impl cp = new MD5Impl(); //根據md5來加密
cp.encrypt(paramters);
} else if (state == DES) {
DESImpl sp = new DESImpl(); //根據des來加密
sp.encrypt(paramters);
} else if (state == REA) {
REAImpl lp = new REAImpl();
lp.encrypt(paramters);
}
... //其他加密
可以看到,需要爲每一個加密工具加一個判斷條件,當加密工具有增減或非常多時,代碼不得不跟着作大量修改。State模式對各種狀態行爲加以抽象,爲每一個可能的狀態創建一個狀態類的子類,並通過一個Context類管理狀態子類對象的當前狀態,對狀態子類的調用加以封裝。用戶可以通過改變Context類對象所管理的狀態來改變不同狀態的行爲。用狀態模式實現的代碼如下:
import java.util.*;
// 加密的接口
interface State {
public void encrypt();
}
class MD5Impl implements State {
@Override
public void encrypt() {
// TODO Auto-generated method stub
System.out.println("md5");
}
}
class DESImpl implements State {
@Override
public void encrypt() {
// TODO Auto-generated method stub
System.out.println("des");
}
}
class REAImpl implements State {
@Override
public void encrypt() {
// TODO Auto-generated method stub
System.out.println("rea");
}
}
// 配置各個工具狀態
class Context {
// 保持各種工具的列表
Map<String, State> toolBar = new HashMap<String, State>();
State toolState;
public void addState(String name,State state){
toolBar.put(name, state);
}
// 改變狀態
public void selectState(String name){
toolState = toolBar.get(name);
}
// 執行具體的動作
public void action(){
toolState.encrypt();
}
}
// 測試類
public class Client {
public static void main(String[] args) {
Context tool = new Context();
tool.addState("MD5", new MD5Impl());
tool.addState("DES",new DESImpl());
tool.addState("REA", new REAImpl());
tool.selectState("MD5");
tool.action();
tool.selectState("DES");
tool.action();
tool.selectState("REA");
tool.action();
}
}
輸出:
MD5
DES
REA