java狀態模式例項解析
狀態模式是一種常用的設計模式,常用於軟體系統中解決多種狀態下行為互異的情況。例如在音視訊播放器中多種狀態各自對應著不相同的處理,使用狀態機可以完美實現解耦。最近在做一個專案的重構,有使用到狀態模式,因此寫這篇文章分享一下。
1、狀態模式概述:
狀態模式(State Pattern):允許一個物件在其內部狀態改變時改變它的行為,物件看起來似乎修改了它的類。其別名為狀態物件(Object for States),狀態模式是一種物件行為型模式。《設計模式的藝術》
1)Context(環境類):環境類擁有各種不同狀態的物件,作為外部使用的介面,負責呼叫狀態類介面。
2)State(抽象狀態):抽象狀態既可以為抽象類,也可以直接定義成介面。主要用於定義狀態抽象方法,具體實現由子類負責。
3)ConcreteState(具體狀態類):具體狀態類為抽象狀態的實現者,不同的狀態類對應這不同的狀態,其內部實現也不相同。環境類中使用不同狀態的物件時,能實現不同的處理邏輯。
2、狀態模式示例:
示例為真實專案,一個即時通訊客戶端連線服務端網路的設計。客戶端連線伺服器時存在多種狀態,最初是通過if-else判斷來實現,程式碼耦合度比較高。使用狀態設計模式之後,程式碼清晰很多,耦合降低。類圖與上面的基本一樣,因此此處不再展示,直接上程式碼。
public interface ConnectState {
void handleRequest();
}
public class InitState implements ConnectState{
private ConnectMachine connectMachine;
private boolean connectResult;
public InitState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
doConnect();
connectMachine.waitingConnect();
}
private void doConnect() {
//connect server
if (connectResult) {
connectSuccess();
} else {
connectFailure();
}
}
private void connectSuccess() {
connectMachine.connectSuccess();
}
private void connectFailure() {
connectMachine.connectFailure();
}
}
public class ConnectingState implements ConnectState{
private ConnectMachine connectMachine;
public ConnectingState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
waitingConnect();
}
private void waitingConnect() {
//loading and do something
}
}
public class ConnectSuccessState implements ConnectState{
private ConnectMachine connectMachine;
public ConnectSuccessState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
connectSuccess();
}
private void connectSuccess() {
//do something
}
}
public class ConnectFailureState implements ConnectState{
private ConnectMachine connectMachine;
public ConnectFailureState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
connectFailure();
}
private void connectFailure() {
//do something
}
}
public class ReConnectingState implements ConnectState{
private ConnectMachine connectMachine;
public ReConnectingState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
reConnect();
}
private void reConnect() {
//disconnect old connect and connect again
connectMachine.disConnect();
connectMachine.doConnect();
}
}
public class DisconnectState implements ConnectState {
private ConnectMachine connectMachine;
public DisconnectState(ConnectMachine connectMachine) {
this.connectMachine = connectMachine;
}
@Override
public void handleRequest() {
disConnect();
}
private void disConnect() {
//do something
}
}
public class ConnectMachine {
private ConnectState initState;
private ConnectState connectingState;
private ConnectState reconnectState;
private ConnectState disConnectState;
private ConnectState connectSuccessState;
private ConnectState connectFailureState;
public ConnectMachine() {
initState = new InitState(this);
connectingState = new ConnectingState(this);
reconnectState = new ReConnectingState(this);
disConnectState = new DisconnectState(this);
connectSuccessState = new ConnectSuccessState(this);
connectFailureState = new ConnectFailureState(this);
}
public void doConnect() {
initState.handleRequest();
}
public void waitingConnect() {
connectingState.handleRequest();
}
public void reConnect() {
reconnectState.handleRequest();
}
public void disConnect() {
disConnectState.handleRequest();
}
public void connectSuccess() {
connectSuccessState.handleRequest();
}
public void connectFailure() {
connectFailureState.handleRequest();
}
}
如果不使用狀態模式,所有的邏輯判斷全部寫在ConnectMachine類裡面,而且是通過大量if-else判斷實現,程式碼可讀性比較差。改成狀態模式之後,實現細節交給具體狀態類去實現,ConnectMachine只是提供給外部系統使用的介面,具體實現對於使用者來說是不可的。因為只是展示狀態模式的設計,使用的是回撥的方式,在專案中使用時可以引入Rxjava,響應式程式設計更加能體會到其中妙處。
3、狀態模式優缺點分析:
優點:
1)面向介面式程式設計,將實現細節巧妙封裝在各個不同的狀態類中,狀態轉換交給狀態類自己去實現,外部無需關心;
2)將由大量業務、大量邏輯判斷的程式碼去除,狀態類內部通過狀態的轉換實現相關邏輯,程式碼可讀性更好;
缺點:
1)增加新的狀態時會增加狀態類,而且在增加新的狀態類之後,環境類需要做相應的修改,不太符合開閉原則;
結束語
狀態模式的介紹就到這,雖然狀態模式在設計上能夠帶來很大優勢。但是也不能濫用,因為對於一些簡單的邏輯,隨意使用狀態模式會使得系統複雜度增加。如果對設計模式感興趣的同學,推薦讀一下《設計模式的藝術》這本書,寫得很實用。
相關文章
- 達夢資料庫例項的狀態和模式資料庫模式
- 3.4.4 檢視例項的靜默狀態
- Java中的單例模式最全解析Java單例模式
- 折騰Java設計模式之狀態模式Java設計模式
- HarmonyOS遠端狀態訂閱開發例項
- 從例項出發,瞭解單例模式和靜態塊單例模式
- 策略模式例項模式
- 單例模式解析單例模式
- 設計模式:狀態模式設計模式
- 設計模式-狀態模式設計模式
- 例項 靜態 類
- 深度解析單例模式單例模式
- Java例項教程Java
- jQuery Ajax 例項 全解析jQuery
- python設計模式狀態模式Python設計模式
- 設計模式(十五)狀態模式設計模式
- 設計模式之——狀態模式設計模式
- 行為型模式:狀態模式模式
- 17_狀態模式模式
- 狀態變化模式模式
- 用設計模式去掉沒必要的狀態變數 —— 狀態模式設計模式變數
- Java進階篇設計模式之十二 ---- 備忘錄模式和狀態模式Java設計模式
- java 單例模式Java單例模式
- Java單例模式Java單例模式
- 設計模式-狀態模式(State Pattern)設計模式
- PHP 設計模式之狀態模式PHP設計模式
- 《Head First 設計模式》:狀態模式設計模式
- 設計模式20之狀態模式設計模式
- 簡說設計模式——狀態模式設計模式
- 極簡設計模式-狀態模式設計模式
- 設計模式之狀態模式(State)設計模式
- GoLang設計模式14 - 狀態模式Golang設計模式
- python設計模式【9】-狀態模式Python設計模式
- Vue原始碼解析:Vue例項Vue原始碼
- Web安全之CSRF例項解析Web
- Java--例項化Java
- 05@多用列舉表示狀態、選項、狀態碼
- 設計模式例項程式碼設計模式