1. 程式人生 > >設計模式--狀態模式

設計模式--狀態模式

狀態模式(State Pattern)

狀態模式,當一個物件的內在狀態改變時允許改變其行為,這個物件看起來就像是改變了其類。狀態模式主要解決的是當控制一個物件的狀態條件表示式過於複雜時的情況。如果一個物件狀態的判斷邏輯過於複雜,會不便於後期系統的維護以及不利於系統擴充套件。在狀態模式中,將狀態的判斷邏輯轉移到了表示不同狀態的一系列類中,這樣每一個類代表著一種狀態,每種狀態的處理功能邏輯單一化、專業化,這樣就大大簡化了判斷的處理邏輯,同時也增強了系統的可讀性,更利於系統維護和擴充套件。

介紹

意圖:允許物件在內部狀態發生改變時改變它的行為,物件看起來好像修改了它的類。
使用場景
1. 一個物件的行為取決於它的狀態,並且它必須在執行時刻根據狀態改變其行為。
2. 一個操作中含有龐大的分支結構,並且這些分支決定於物件的狀態。
優點


1. 封裝了轉換規則。
2. 列舉可能的狀態,在列舉狀態之前需要確定狀態種類。
3. 將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變物件狀態即可改變物件行為。
4. 允許狀態轉換邏輯與狀態物件合成一體,而不是某一個巨大的條件語句塊。
5. 可以讓多個環境物件共享一個狀態物件,從而減少系統中物件的個數。
缺點
1. 狀態模式的使用必然會增加系統類和物件的個數。
2. 狀態模式的結構和實現都較為複雜,如果使用不當講導致程式結構和程式碼的混亂。
3. 狀態模式對開閉原則的支援並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態切換的原始碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的原始碼。
注意事項
:在行為受狀態約束的時候使用狀態模式,而且狀態一般不超過5個。

實現

在狀態模式的例項中,我們模擬一個文字檔案編輯和預覽的功能。編輯和預覽兩種狀態,分別對應不同的操作。

步驟 1

建立一個狀態介面。
IState.java

package com.mrcsj.test.study.state;


/**
 * 狀態介面
 * @author admin
 * @version 1.0
 * @created 19-十二月-2016 17:07:07
 */
public interface IState {

    /**
     * 新增
     * 
     * @param context
     */
    public void add(Context context);

    /**
     * 狀態轉換
     * 
     * @param context
     * @param mode
     */
    public void convertState(Context context, int mode);

    /**
     * 修改
     * 
     * @param context
     */
    public void modify(Context context);

    /**
     * 儲存
     * 
     * @param context
     */
    public void save(Context context);

    /**
     * 檢視
     * 
     * @param context
     */
    public void view(Context context);

}

步驟 2

建立一下上下文,用來切換當前編輯和預覽狀態。
Context.java

package com.mrcsj.test.study.state;


/**
 * 上下文環境,用來決定使用哪一種狀態
 * @author admin
 * @version 1.0
 * @created 19-十二月-2016 17:07:07
 */
public class Context {

    public static final int EDIT_MODE = 0;
    public static final int PREVIEW_MODE = 1;
    private IState state;

    public Context(){

    }

    public void finalize() throws Throwable {

    }
    /**
     * 
     * @param state
     */
    public void changeState(IState state){
        this.state = state;
    }

    /**
     * 改變狀態
     * 
     * @param mode
     */
    public void doWork(int mode){
        this.state.convertState(this, mode);
        this.state.add(this);
        this.state.save(this);
        this.state.modify(this);
        this.state.view(this);
    }
}//end Context

步驟 3

建立編輯和預覽兩種狀態實現類。
編輯
EditState.java

package com.mrcsj.test.study.state;


/**
 * @author admin
 * @version 1.0
 * @created 19-十二月-2016 17:07:07
 */
public class EditState implements IState {

    public EditState(){

    }

    public void finalize() throws Throwable {

    }
    /**
     * 新增
     * 
     * @param context
     */
    public void add(Context context){
        System.out.println("【編輯模式】。。。新增");
    }

    /**
     * 狀態轉換
     * 
     * @param context
     * @param mode
     */
    public void convertState(Context context, int mode){
        if(mode == Context.PREVIEW_MODE) {
            context.changeState(new PreviewState());
        }
    }

    /**
     * 修改
     * 
     * @param context
     */
    public void modify(Context context){
        System.out.println("【編輯模式】。。。修改");
    }

    /**
     * 儲存
     * 
     * @param context
     */
    public void save(Context context){
        System.out.println("【編輯模式】。。。儲存");
    }

    /**
     * 檢視
     * 
     * @param context
     */
    public void view(Context context){
        System.out.println("【編輯模式】。。。檢視");
    }
}//end EditState

預覽
PreviewState.java

package com.mrcsj.test.study.state;


/**
 * @author admin
 * @version 1.0
 * @created 19-十二月-2016 17:07:07
 */
public class PreviewState implements IState {

    public PreviewState(){

    }

    public void finalize() throws Throwable {

    }
    /**
     * 新增
     * 
     * @param context
     */
    public void add(Context context){
        System.out.println("【預覽模式】。。。無新增功能");
    }

    /**
     * 狀態轉換
     * 
     * @param context
     * @param mode
     */
    public void convertState(Context context, int mode){
        if(mode == Context.EDIT_MODE) {
            context.changeState(new EditState());
        }
    }

    /**
     * 修改
     * 
     * @param context
     */
    public void modify(Context context){
        System.out.println("【預覽模式】。。。無修改功能");
    }

    /**
     * 儲存
     * 
     * @param context
     */
    public void save(Context context){
        System.out.println("【預覽模式】。。。無儲存功能");
    }

    /**
     * 檢視
     * 
     * @param context
     */
    public void view(Context context){
        System.out.println("【預覽模式】。。。檢視");
    }
}//end PreviewState

步驟 4

建立客戶端,進行測試。
Client.java

package com.mrcsj.test.study.state;

import java.util.Random;

/**
 * 客戶端
 * @author admin
 * @version 1.0
 * @created 19-十二月-2016 17:07:06
 */
public class Client {

    public Client(){

    }

    public void finalize() throws Throwable {

    }

    public static void main(String[] args) {
        Context context = new Context();
        context.changeState(new EditState());
        Random r = new Random();
        for(int i = 0; i < 5; i ++) {
            int x = r.nextInt(2);
            System.out.println("當前模式:" + (x == 0 ? "編輯模式" : x == 1 ? "預覽模式" : ""));
            context.doWork(x);
        }
    }
}//end Client

步驟 5

驗證輸出。

當前模式:預覽模式
【預覽模式】。。。無新增功能
【預覽模式】。。。無儲存功能
【預覽模式】。。。無修改功能
【預覽模式】。。。檢視
當前模式:預覽模式
【預覽模式】。。。無新增功能
【預覽模式】。。。無儲存功能
【預覽模式】。。。無修改功能
【預覽模式】。。。檢視
當前模式:預覽模式
【預覽模式】。。。無新增功能
【預覽模式】。。。無儲存功能
【預覽模式】。。。無修改功能
【預覽模式】。。。檢視
當前模式:預覽模式
【預覽模式】。。。無新增功能
【預覽模式】。。。無儲存功能
【預覽模式】。。。無修改功能
【預覽模式】。。。檢視
當前模式:編輯模式
【編輯模式】。。。新增
【編輯模式】。。。儲存
【編輯模式】。。。修改
【編輯模式】。。。檢視

相關推薦

Java與設計模式-狀態模式

維護 chan str else 開關 進行 private 接下來 csdn 概念:狀態模式把所研究的對象的行為包裝在不同的狀態對象裏。每個狀態對象都屬於一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候。其行為也隨之改變,也就是不同狀態相應

設計模式-狀態模式(25)

java 可能 strac 以及 main 沒有 bject 角色 mage 定義 狀態模式(State Pattern)又稱為狀態對象模式,該模式允許一個對象在其內部狀態改變的時候改變行為。 英文:Allow an object to alert its behavi

設計模式-狀態模式

設計模式 狀態模式 abstract class State { public abstract void Execute(Context context); } class StateA : State { public overrid

PHP設計模式 - 狀態模式

div 技術分享 改變 ace In turn fun 實現 委托 狀態模式當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。狀態模式主要解決的是當控制一個對象狀態的條件表達式過於復雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把復雜

PHP設計模式——狀態模式

前言 狀態設計模式是Gof提出的最吸引人的模式之一,也是一種最有用的模式。遊戲通常就採用狀態模式,因為遊戲中的物件往往會非常頻繁地改變狀態。狀態模式的作用就是允許物件在狀態改變時改變其行為。還有很多其他模擬應用(不一定是遊戲)也依賴於狀態模式。本文將會談到並舉例說明。 按照傳統思維,如果有多個狀

設計模式 狀態模式

class WorkState: def __init__(self): pass def work(self): pass class Monday(WorkState): def work(self, w): if w.day

設計模式 --- 狀態模式

1.定義 當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。 狀態模式把物件的行為包裝在不同的狀態物件裡,每一個狀態物件都有一個共同抽象狀態基類。狀態模式的意圖是讓一個物件在其內部狀態改變的時候其行為也隨之改變。   2.使用場景 1)一個物件的行

軟考設計模式——狀態模式(C++篇)

狀態模式顧名思義就是通過改變狀態來控制物件的行為。 設計思路簡而言之,就是有一個物件,這個物件需要一些狀態,用狀態當引數去例項化這個物件,然後根據一些引數的改變,去改變這個物件的狀態,然後讓這個物件根據狀態的不同做不同的行為。 舉個簡單的例子,把一個人(這個人會例

設計模式-狀態模式(State)

概述 定義 : 允許一個物件在其內部狀態改變時, 改變它的行為 型別 : 行為型 適用場景 一個物件存在多個狀態(不同狀態下行為不同), 且狀態可相互轉換 優點 將不同的狀態隔離 把各種狀態的轉換邏輯分佈到State子類中, 減少相互間

設計模式-狀態模式(State)

狀態模式是行為模式的一種,狀態模式允許改變物件內部狀態來改變物件的行為。 角色和職責: 1.上下文(Context)-Order:    擁有內部的狀態 2.狀態介面(Status)-State:     一個所有具體狀態的共同介面;任何狀態都實現這

C#設計模式-狀態模式

using System; using System.Collections.Generic; namespace TestCSharp { class Program { static void Main(string[] args) {

移動開發之設計模式- 狀態模式(IOS&Android)

資源 完全參照狀態模式|菜鳥教程但不包括IOS程式碼 介紹 意圖: 允許物件在內部狀態發生改變時改變它的行為,物件看起來好像修改了它的類。 主要解決: 物件的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為。 何時使用: 程式碼中包含大量與物件狀態有關的條件

一天一種設計模式——狀態模式

作用:當人物有複雜的狀態轉換時使用 Context:狀態擁有者 State:狀態的介面類 狀態擁有著持有一個狀態的介面類,在構造方法時定義其狀態 狀態的介面類中持有狀態的擁有者,可在每一個狀態內部切換其狀態擁有者的狀態 //程式碼執行 public class Text { Contex

python設計模式-狀態模式

問題:有一個糖果公司需要設計一個糖果售賣機,控制流程如下圖,需要怎麼實現? 這是一個狀態圖,每個圓圈都是一種狀態。很明顯,有有25分錢、 沒有25分錢、 售出糖果、 糖果售罄四個狀態,同時也對應四個動作:投入25分錢,退回25分錢,轉動曲柄和發放糖果。 那如何從狀態圖得到真正的

C++設計模式——狀態模式

在闡述狀態模式之前,先來看一個例子。一個銀行取款問題: 如果賬戶餘額大於0,則正常取款;如果餘額在-2000和0之間,則透支取款;如果餘額小於-2000,則賬戶處於凍結狀態,無法進行取款操作。     實現程式碼如下: //銀行賬戶 class Account { pr

22-Python與設計模式--狀態模式

一、電梯控制器 電梯在我們周邊隨處可見,電梯的控制邏輯中心是由電梯控制器實現的。電梯的控制邏輯,即使簡單點設計,把狀態分成開門狀態,停止狀態和執行狀態,操作分成開門、關門、執行、停止,那流程也是很複雜的。首先,開門狀態不能開門、執行、停止;停止狀態不能關門,停止;執行狀態不能開門、關門、執行。要用一個一個i

unity設計模式-狀態模式

狀態模式在狀態模式(State Pattern)中,類的行為是基於它的狀態改變的。這種型別的設計模式屬於行為型模式。在狀態模式中,我們建立表示各種狀態的物件和一個行為隨著狀態物件改變而改變的 context 物件。介紹意圖:允許物件在內部狀態發生改變時改變它的行為,物件看起來

Android中設計模式--狀態模式(將動作委託到當前狀態狀態之間可以互相轉換)

   狀態模式:將狀態封裝成為獨立類,並將動作委託到當前狀態;狀態之間可以相互轉換,因為實現了相同的介面;狀態改變,則動作會跟著改變。  理解: 1.定義狀態介面,所有的狀態均實現該介面,這樣對於客戶(呼叫者)來說,狀態是可以替換的,客戶不關心具體的狀態是什麼,只是呼叫介

設計模式--狀態模式

狀態模式(State Pattern) 狀態模式,當一個物件的內在狀態改變時允許改變其行為,這個物件看起來就像是改變了其類。狀態模式主要解決的是當控制一個物件的狀態條件表示式過於複雜時的情況。如果一個物件狀態的判斷邏輯過於複雜,會不便於後期系統的維護以及不利於

遊戲開發中的設計模式——狀態模式

Siki學院——遊戲開發中的設計模式 狀態模式—— 菜鳥篇個人學習筆記 案例開發——應用於場景轉換 由StartState場景,自動跳轉到MainMenuState場景,點選按鈕後,跳轉到BattleState場景  GameLoop 採用了指令碼和遊戲物體