引言
??上一節(jié)我們說了策略模式燕刻。這一節(jié)我們講講策略模式的雙胞胎弟弟:狀態(tài)模式脸爱,這個(gè)模式大家可能不常見,也不常用昼丑,但是我們還是需要了解一下呻逆。
示例地址
??Demo
依然是類圖
在看定義
??當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來就是改變了其類矾克。
使用場(chǎng)景
?? 1. 一個(gè)對(duì)象的行為取決于它的狀態(tài)页慷,并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為。
??2. 代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語句胁附,例如酒繁,一個(gè)操作中含有龐大的多分支語句(if-else或者switch-case),且這些分支依賴于該對(duì)象的狀態(tài)控妻。
狀態(tài)模式的作用
??將每一個(gè)條件分支放入一個(gè)獨(dú)立的類中州袒,這是的你可以根據(jù)對(duì)象自身的情況將對(duì)象的狀態(tài)作為一個(gè)對(duì)象,這一對(duì)象可以不依賴于其他對(duì)象而獨(dú)立變化弓候,這樣通過多態(tài)來去除過多的郎哭、重復(fù)的if-else等分支語句。
狀態(tài)模式的示例
??我們上初中的時(shí)候都學(xué)過物理菇存,知道液化夸研、升華、氣化依鸥,大自然的水也有這三種狀態(tài)固體亥至、液體、氣體,不同的狀態(tài)有不同的表現(xiàn)形式姐扮,固態(tài)是冰絮供,液態(tài)是水,氣態(tài)就是水蒸氣了茶敏。
1. 定義一個(gè)狀態(tài)接口
/**
* 水的狀態(tài)
*
* @author 512573717@qq.com
* @created 2018/7/12 下午4:15.
*/
public interface IState {
// 什么形狀
void shape();
// 什么用途
void use();
}
2. 各種狀態(tài)的實(shí)現(xiàn)
/**
* 固體
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:07.
*/
public class IceState implements IState {
@Override
public void shape() {
System.out.println("這是0度以下的水 固體的");
}
@Override
public void use() {
System.out.println("當(dāng)前用途:可以用來存儲(chǔ)蔬菜壤靶,保鮮的作用");
}
}
/**
* 液體
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:11.
*/
public class FluidState implements IState {
@Override
public void shape() {
System.out.println("這是0度到100之間的水 液體的");
}
@Override
public void use() {
System.out.println("當(dāng)前用途:洗澡、澆樹");
}
}
/**
* 氣體
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:10.
*/
public class GasState implements IState {
@Override
public void shape() {
System.out.println("這是100度以上的水 氣體的");
}
@Override
public void use() {
System.out.println("當(dāng)前用途:用來真桑拿惊搏、食品等");
}
}
3. 狀態(tài)管理類
/**
* 狀態(tài)管理類
*
* @author 512573717@qq.com
* @created 2018/7/12 下午5:12.
*/
public class ClientContext {
private IState mIState = new IceState();
private static volatile ClientContext mClientContext;
private ClientContext() {
}
public static ClientContext getInstance() {
if (null == mClientContext) {
synchronized (ClientContext.class) {
if (null == mClientContext) {
mClientContext = new ClientContext();
}
}
}
return mClientContext;
}
public void setIState(IState IState) {
mIState = IState;
}
public void use() {
mIState.use();
}
public void shape() {
mIState.shape();
}
}
4. Client使用
// 默認(rèn)是固態(tài)的水
ClientContext.getInstance().use();
//液態(tài)的水
ClientContext.getInstance().setIState(new FluidState());
ClientContext.getInstance().use();
// 氣態(tài)
ClientContext.getInstance().setIState(new GasState());
ClientContext.getInstance().use();
總結(jié)
??狀態(tài)模式主要是避免代碼膨脹贮乳,同時(shí)保證程序的擴(kuò)展性和維護(hù)性。
策略模式與狀態(tài)模式的區(qū)別
??策略模式:封裝一系列平行且復(fù)雜多變的實(shí)現(xiàn)方式胀屿。
??狀態(tài)模式:實(shí)現(xiàn)把對(duì)象的內(nèi)在狀態(tài)的變化封裝起來塘揣,用外部行為來表現(xiàn)出來。