AlbumCameraRecorder項目隨着功能的添加,代碼變得笨重了起來,由於核心代碼裏面有多個狀態的互相轉變,不同場景又有不同狀態的處理,導致後期擴展維護很難,便使用了這個狀態模式優化。
直接進入主題優缺點
優點:
- 將與狀態相關的行爲局部化,並且將不同狀態分割開來,消除了龐大的條件分支語句,通過各種狀態把邏輯分佈到state。方便後期維護代碼。
- 新增新的狀態非常容易,易於擴展。
缺點:
- 必然性的會增加系統中類和對象的個數,因爲多個狀態之間可以互相切換,使用不當會導致系統的複雜性增加,可讀性差,這些都需要良好的代碼功力設計全面。
在具體講解狀態模式之間,先了解AlbumCameraRecorder項目的一個簡單邏輯,該項目有個拍攝類CameraLayout
,它需要根據當前不同狀態比如拍攝照片、拍攝錄像等等做相對應的處理。那麼我們開始吧!
通過AlbumCameraRecorder項目讓我們看看由哪些類組成這個狀態模式
通過思維導圖,state包下面的類他們之間的關係如圖:
因爲源碼代碼過多,所以這邊抽取核心部分讓大家更快了解:
StateInterface 狀態接口
public interface StateInterface {
/**
* 提交核心事件
*/
void pvLayoutCommit();
/**
* 取消核心事件
*/
void pvLayoutCancel();
}
StateMode 狀態抽象父類
public abstract class StateMode implements StateInterface {
/**
* 用於子類使用,cameraLayout是處理邏輯,cameraStateManagement是處理狀態轉換
*/
CameraStateManagement cameraStateManagement;
CameraLayout cameraLayout;
}
多個狀態子類,抽出兩個Preview和VideoIn
public class Preview extends StateMode {
@Override
public void pvLayoutCommit() {
// 處理邏輯
cameraLayout.xxxx();
// 轉變視頻錄製中的狀態
cameraStateManagement.setState(cameraStateManagement.getVideoIn());
}
@Override
public void pvLayoutCancel() {
// 處理邏輯
cameraLayout.xxxx();
}
}
public class VideoIn extends StateMode {
@Override
public void pvLayoutCommit() {
// 處理邏輯
cameraLayout.xxxx();
// 轉變視頻錄製中的狀態
cameraStateManagement.setState(cameraStateManagement.getPreview());
}
@Override
public void pvLayoutCancel() {
// 處理邏輯
cameraLayout.xxxx();
}
}
CameraLayout拍攝類,優化代碼的對象
public class CameraLayout {
/**
* 狀態管理
*/
public final CameraStateManagement mCameraStateManagement;
public void commit() {
// 處理當前狀態的相對應邏輯
mCameraStateManagement.pvLayoutCommit();
}
public void cancel() {
// 處理當前狀態的相對應邏輯
mCameraStateManagement.pvLayoutCancel();
}
}
CameraStateManagement狀態管理
public class CameraStateManagement implements StateInterface {
CameraLayout mCameraLayout;
/**
* 當前狀態
*/
StateInterface state;
/**
* 預覽狀態
*/
StateInterface preview;
/**
* 正在錄製視頻中的狀態
*/
StateInterface videoIn;
public CameraStateManagement(CameraLayout cameraLayout) {
mCameraLayout = cameraLayout;
// 初始化相關狀態邏輯
preview = new Preview(cameraLayout, this);
videoIn = new VideoIn(cameraLayout, this);
// 設置當前默認狀態
state = preview;
}
/**
* @return 當前狀態
*/
public StateInterface getState() {
return state;
}
/**
* 賦值當前狀態
*/
public void setState(StateInterface state) {
this.state = state;
}
@Override
public void pvLayoutCommit() {
state.pvLayoutCommit();
}
@Override
public void pvLayoutCancel() {
state.pvLayoutCancel();
}
}
那麼該模式的核心代碼都在這裏了,改完後的代碼作者不管維護還是添加代碼都十分舒適,這就是優雅代碼帶來的好處了吧!
也歡迎小夥伴指出更好的改進,喜歡點個收藏謝謝支持!