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)增加新的狀態時會增加狀態類,而且在增加新的狀態類之後,環境類需要做相應的修改,不太符合開閉原則;
結束語
狀態模式的介紹就到這,雖然狀態模式在設計上能夠帶來很大優勢。但是也不能濫用,因為對於一些簡單的邏輯,隨意使用狀態模式會使得系統複雜度增加。如果對設計模式感興趣的同學,推薦讀一下《設計模式的藝術》這本書,寫得很實用。
相關文章
- 達夢資料庫例項的狀態和模式資料庫模式
- Java解析Excel例項解析JavaExcel
- oracle資料庫例項狀態Oracle資料庫
- Java設計模式之狀態模式Java設計模式
- java單例模式深度解析Java單例模式
- 折騰Java設計模式之狀態模式Java設計模式
- JAVA設計模式之 狀態模式【State Pattern】Java設計模式
- 從狀態模式看 JavaScript 與 Java模式JavaScript
- Java XML程式設計例項解析JavaXML程式設計
- 例項解析Oracle是共享模式還是專用模式Oracle模式
- Java中的單例模式最全解析Java單例模式
- 狀態模式模式
- 例項講解Java工廠模式Java模式
- 策略模式與簡單java例項模式Java
- 詳解 state 狀態模式及在 C++ 設計模式程式設計中的使用例項C++設計模式程式設計
- HarmonyOS遠端狀態訂閱開發例項
- Android 動態載入資源例項解析Android
- JavaStatePattern(狀態模式)JavaAST模式
- JS 狀態模式JS模式
- (三)狀態模式模式
- 狀態模式(State)模式
- Pull解析例項
- 設計模式-狀態模式設計模式
- 設計模式:狀態模式設計模式
- Java 非同步回撥機制例項解析Java非同步
- 從例項出發,瞭解單例模式和靜態塊單例模式
- 單例模式解析單例模式
- Redo active狀態解析
- css設定連結a的狀態的例項程式碼CSS
- 策略模式例項模式
- JAVA中動態性例項解釋 (轉)Java
- UML用例圖例項解析
- 行為型模式:狀態模式模式
- 設計模式(十五)狀態模式設計模式
- 設計模式之——狀態模式設計模式
- javascript設計模式狀態模式JavaScript設計模式
- 設計模式(六):狀態模式設計模式
- 狀態變化模式模式