編輯:關於android開發
狀態模式中的行為是由狀態來決定,不同的狀態下有不同的行為。當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。
1.一個對象的行為取決於它的狀態,並且它必須在運行時根據狀態改變它的行為。
2.代碼中包含大量與對象狀態有關的條件語句,例如,一個操作中含有大量的多分支語句,且這些分支依賴於該對象的狀態。
實現效果:首先將電視的狀態分為開機與關機狀態,開機時可以通過遙控器實現頻道切換和調節音量,但是關機時,這些操作都會失效。
首先是普通的實現方法:
public class TVController {
//開機狀態
private final static int POWER_ON = 1;
//關機狀態
private final static int POWER_OFF = 2;
//默認狀態
private int mState = POWER_OFF;
public void powerOn(){
if(mState ==POWER_OFF){
System.out.println("電視開機了");
}
mState = POWER_ON;
}
public void powerOff(){
if(mState ==POWER_ON){
System.out.println("電視關機了");
}
mState = POWER_OFF;
}
public void nextChannel(){
if(mState ==POWER_ON){
System.out.println("下一頻道");
}else{
System.out.println("沒有開機");
}
}
public void prevChannel(){
if(mState ==POWER_ON){
System.out.println("上一頻道");
}else{
System.out.println("沒有開機");
}
}
public void turnUp(){
if(mState ==POWER_ON){
System.out.println("調高音量");
}else{
System.out.println("沒有開機");
}
}
public void turnDown(){
if(mState ==POWER_ON){
System.out.println("調低音量");
}else{
System.out.println("沒有開機");
}
}
}
可以看到,每次執行通過判斷當前狀態來進行操作,部分的代碼重復,假設狀態和功能增加,就會越來越難以維護。這時可以使用狀態模式,如下:
電視的操作
/**
* 電視狀態接口,定義了電視的操作函數
*
* */
public interface TVState {
public void nextChannel();
public void prevChannel();
public void turnUp();
public void turnDown();
}
關機狀態
/**
*
* 關機狀態,操作無結果
*
* */
public class PowerOffState implements TVState{
@Override
public void nextChannel() {
}
@Override
public void prevChannel() {
}
@Override
public void turnUp() {
}
@Override
public void turnDown() {
}
}
開機狀態
/**
*
* 開機狀態,操作有效
*
* */
public class PowerOnState implements TVState{
@Override
public void nextChannel() {
System.out.println("下一頻道");
}
@Override
public void prevChannel() {
System.out.println("上一頻道");
}
@Override
public void turnUp() {
System.out.println("調高音量");
}
@Override
public void turnDown() {
System.out.println("調低音量");
}
}
電源操作接口
/**
* 電源操作接口
*
* */
public interface PowerController {
public void powerOn();
public void powerOff();
}
電視遙控器
/**
* 電視遙控器
*
* */
public class TVController implements PowerController{
TVState mTVState;
public void setTVState(TVState mTVState){
this.mTVState = mTVState;
}
@Override
public void powerOn() {
setTVState(new PowerOnState());
System.out.println("開機了");
}
@Override
public void powerOff() {
setTVState(new PowerOffState());
System.out.println("關機了");
}
public void nextChannel(){
mTVState.nextChannel();
}
public void prevChannel(){
mTVState.prevChannel();
}
public void turnUp(){
mTVState.turnUp();
}
public void turnDown(){
mTVState.turnDown();
}
}
調用:
public class Client {
public static void main(String[] args) {
TVController tvController = new TVController();
//設置開機狀態
tvController.powerOn();
//下一頻道
tvController.nextChannel();
//調高音量
tvController.turnUp();
//關機
tvController.powerOff();
//調低音量,此時不會生效
tvController.turnDown();
}
}
結果
開機了
下一頻道
調高音量
關機了
可以看出,狀態模式將這些行為封裝到狀態類中,在進行操作時將這些功能轉發給狀態對象,不同的狀態有不同的實現,去除了重復了if-else語句,這正是狀態模式的精髓所在。
狀態模式與策略模式的結構幾乎是一樣的,就像是孿生兄弟。但是他們的目地、本質不一樣。狀態模式的行為是平行的、不可替換的,策略模式的行為是彼此獨立的、可相互替換的。狀態模式,通常是自我控制狀態的改變。而策略模式,是由外部指定使用什麼樣的策略。
1.登錄系統,根據用戶是否登錄,判斷事件的處理方式。
2.Wi-Fi管理,在不同的狀態下,WiFi的掃描請求處理不一。
將所有與一個特定的狀態相關的行為都放入一個狀態對象中,它提供了一個更好的方法來組織與特定狀態相關的代碼,將繁瑣的狀態判斷轉換成結構清晰的狀態類族,在避免代碼膨脹的同時也保證了可擴展性與可維護性。
狀態模式的使用必然會增加系統類和對象的個數。
Android端 配置極光推送 因為業務需要,android客戶端需要加推送,原來采用的百度推送,但是小米手機有時候收不到,後來換成了極光推送,極光的話所有設備都能收到推
如何解決Linux系統中的Navicat for MySQL 1045錯誤Navicat連接MySQL數據庫時難免會遇到1045錯誤,主要是因為用戶輸入的用戶名或密碼錯誤
【React Native開發】React Native控件之ViewPagerAndroid講解以及美團首頁頂部效果實例(17) (一)前言 今天我們一起來看一下V
我的Android進階之旅------Android 5.0中出現警告的解決方法: Service Intent must be explicit: 1.錯誤描述 今