国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計模式學(xué)習(xí)筆記 - 設(shè)計模式與范式 -行為型:8.狀態(tài)模式:游戲、工作流引擎中常用的狀態(tài)機是如何實現(xiàn)的?

這篇具有很好參考價值的文章主要介紹了設(shè)計模式學(xué)習(xí)筆記 - 設(shè)計模式與范式 -行為型:8.狀態(tài)模式:游戲、工作流引擎中常用的狀態(tài)機是如何實現(xiàn)的?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

本章學(xué)習(xí)狀態(tài)模式。在實際的開發(fā)中,狀態(tài)模式并不是很常用,但是在能夠用到的場景里,它可以發(fā)揮很大的作用。從這一點上看,它有點像我們之前講到的組合模式。

狀態(tài)模式一般用來實現(xiàn)狀態(tài)機,而狀態(tài)機常用在游戲、工作流引擎等系統(tǒng)開發(fā)中。不過,狀態(tài)機的實現(xiàn)方式有很多種,除了狀態(tài)模式,比較常用的還有分支邏輯法和查表法。本章就詳細(xì)講講這幾種實現(xiàn)方式,并且對比一下它們的優(yōu)劣和應(yīng)用場景。


什么是有限狀態(tài)機

有限狀態(tài)機,英文翻譯是 Finite State Machine,縮寫為 FSM,簡稱狀態(tài)機。狀態(tài)機有三個組成部分:狀態(tài)(State)、事件(Event)、動作(Action)。

  • 事件也稱為轉(zhuǎn)移條件(Transaction Condition)。
  • 事件觸發(fā)狀態(tài)的轉(zhuǎn)移及動作的執(zhí)行。
  • 不過,動作不是必須得,也可能只轉(zhuǎn)移狀態(tài),不執(zhí)行任何動作。

對于剛剛給出的狀態(tài)機定義,結(jié)合一個具體的例子進(jìn)行解釋。

“超級馬里奧” 游戲不知道你玩過沒有?在游戲中,馬里奧可以變身為多種形態(tài),比如小馬里奧(Small Mario)、超級馬里奧(Super Mario)、火焰馬里奧(Fire Mario)、斗篷馬里奧(Cape Mario)等等。在不同的游戲情節(jié)下,各個形態(tài)會互相轉(zhuǎn)化,并相應(yīng)地增減積分。比如,初始狀態(tài)是小馬里奧,吃了蘑菇后就變成超級馬里奧,并且增加 100 積分。

實際上,馬里奧形態(tài)的轉(zhuǎn)變就是一個狀態(tài)機。其中,馬里奧的不同形態(tài)就是狀態(tài)機種的 “狀態(tài)”,游戲情節(jié)(比如吃了蘑菇)就是狀態(tài)機種的 “事件”,加減積分就是狀態(tài)機種的 “動作”。比如,吃蘑菇這個事件,會觸發(fā)狀態(tài)的轉(zhuǎn)移(從小馬里奧轉(zhuǎn)移到超級馬里奧),以及觸發(fā)動作的執(zhí)行(增加 100 積分)。

為方便講解,我對游戲背景做了簡化,只保留了部分狀態(tài)和事件,簡化之后的狀態(tài)轉(zhuǎn)移如下所示:

設(shè)計模式學(xué)習(xí)筆記 - 設(shè)計模式與范式 -行為型:8.狀態(tài)模式:游戲、工作流引擎中常用的狀態(tài)機是如何實現(xiàn)的?,設(shè)計模式-實戰(zhàn),狀態(tài)模式
如何編程來實現(xiàn)上面的狀態(tài)機呢?

我寫了個骨架代碼,如下所示。其中,obtainMushRoom()、obtainCape()、obtainFileFlower()、meetMonster() 這個幾個函數(shù),能夠根據(jù)當(dāng)前的狀態(tài)和事件,更新狀態(tài)和增減積分。不過,具體的代碼實現(xiàn)暫時沒給出。你可以先試著自己補全一下。

public enum State {
    SMALL(0),
    SUPER(1),
    FIRE(2),
    CAPE(3),
    ;

    private int value;

    State(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

public class MarioStateMachine {
    private int score;
    private State currentState;

    public MarioStateMachine() {
        this.score = 0;
        this.currentState = State.SMALL;
    }

    public void obtainMushRoom() {
        //TODO
    }

    public void obtainCape() {
        //TODO
    }

    public void obtainFireFlower() {
        //TODO
    }

    public void meetMonster() {
        //TODO
    }

    public int getScore() {
        return score;
    }

    public State getState() {
        return currentState;
    }
}

public class ApplicationDemo {
    public static void main(String[] args) {
        MarioStateMachine mario = new MarioStateMachine();
        mario.obtainMushRoom();
        int score = mario.getScore();
        State state = mario.getState();
        System.out.println("mario score: " + score + "; state: " + state);
    }
}

狀態(tài)機實現(xiàn)方式一:分支邏輯法

對于如何實現(xiàn)狀態(tài)機,有三種方式。其中,最簡單直接的實現(xiàn)方式是,參照狀態(tài)轉(zhuǎn)移圖,將每一個狀態(tài)轉(zhuǎn)移,原模原樣地直譯成代碼。這樣編寫的代碼會包含大量的 if-esle 或 switch-else 分支判斷邏輯,甚至是嵌套的分支判斷邏輯,所以,我把這種方法暫且命名為分支邏輯法

按照這個思路,將上面的骨架代碼補全一下。補全之后的代碼如下所示:

public class MarioStateMachine {
    private int score;
    private State currentState;

    public MarioStateMachine() {
        this.score = 0;
        this.currentState = State.SMALL;
    }

    public void obtainMushRoom() {
        if (currentState == State.SMALL) {
            this.currentState = State.SUPER;
            this.score += 100;
        }
    }

    public void obtainCape() {
        if (currentState == State.SMALL || currentState == State.SUPER) {
            this.currentState = State.CAPE;
            this.score += 200;
        }
    }

    public void obtainFireFlower() {
        if (currentState == State.SMALL || currentState == State.SUPER) {
            this.currentState = State.FIRE;
            this.score += 300;
        }
    }

    public void meetMonster() {
        if (currentState == State.SUPER) {
            this.currentState = State.SMALL;
            this.score -= 100;
        }
        if (currentState == State.CAPE) {
            this.currentState = State.SMALL;
            this.score -= 200;
        }
        if (currentState == State.FIRE) {
            this.currentState = State.SMALL;
            this.score -= 300;
        }
    }

    public int getScore() {
        return score;
    }

    public State getState() {
        return currentState;
    }
}

對于簡單的狀態(tài)機來說,分支邏輯這種實現(xiàn)方式是可以接收的。但是,對于復(fù)雜的狀態(tài)機來說,這種實現(xiàn)方式及其容易漏寫或錯寫某個狀態(tài)轉(zhuǎn)移。此外,代碼中充斥著大量的 if-else 或者 switch-case 分支判斷邏輯,可讀性和可維護(hù)性都很差。如果哪些修改了狀態(tài)機種的某個轉(zhuǎn)移,我們要在冗長的分支邏輯中找到對應(yīng)地代碼進(jìn)行修改,很容易改錯,引入 BUG。

狀態(tài)機實現(xiàn)方式二:查表法

實際上,上面的實現(xiàn)方式有點類似 hard code,對于復(fù)雜的狀態(tài)機來說不適用,而狀態(tài)機的第二種實現(xiàn)方式查表法,就更加合適了。接下來,看下如何利用查表法來補全骨架代碼。

實際上,除了用狀態(tài)轉(zhuǎn)移圖來表示之外,狀態(tài)機還可以用二維表來表示,如下所示。這個二維表中,第一維表示當(dāng)前的狀態(tài),第二維表示當(dāng)前狀態(tài)經(jīng)過事件之后,轉(zhuǎn)移到的新狀態(tài)及其執(zhí)行的動作。

E1(Got MushRoom) E2(Got Cape) E3(Got Fire Flower) E4(Meet Monster)
Small Super/+100 Cape/+200 Fire/+300 /
Super / Cape/+200 Fire/+300 Small/-100
Cape / / / Small/-200
Fire / / / Small/-300

注:表中的斜杠表示不存在這種狀態(tài)轉(zhuǎn)移

相對于分支邏輯的實現(xiàn)方式,查表法的代碼實現(xiàn)更加清晰,可讀性和可維護(hù)性更好。當(dāng)修改狀態(tài)機時,我們只需要修改 transactionTableactionTable 兩個二維數(shù)組即可。實際上,如果我們把二維數(shù)組存儲在配置文件中,當(dāng)需要修改狀態(tài)機時,甚至可以不修改代碼,只需要修改配置文件就可以了。具體代碼如下所示:

public enum Event {
    GOT_MUSHROOM(0),
    GOT_CAPE(1),
    GOT_FIRE(2),
    MEET_MONSTER(3),
    ;

    private int value;

    Event(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

public class MarioStateMachine {
    private int score;
    private State currentState;

    private static final State[][] transitionTable = {
            {SUPER, CAPE, FIRE, SMALL},
            {SUPER, CAPE, FIRE, SMALL},
            {CAPE, CAPE, CAPE, SMALL},
            {FIRE, FIRE, FIRE, SMALL}
    };

    private static final int[][] actionTable = {
            {100, 200, 300, 0},
            {0, 200, 300, -100},
            {0, 0, 0, -200},
            {0, 0, 0, -300},
    };

    public MarioStateMachine() {
        this.score = 0;
        this.currentState = State.SMALL;
    }

    public void obtainMushRoom() {
        executeEvent(Event.GOT_MUSHROOM);
    }

    public void obtainCape() {
        executeEvent(Event.GOT_CAPE);
    }

    public void obtainFireFlower() {
        executeEvent(Event.GOT_FIRE);
    }

    public void meetMonster() {
        executeEvent(Event.MEET_MONSTER);
    }

    private void executeEvent(Event event) {
        int stateValue = currentState.getValue();
        int eventValue = event.getValue();
        this.currentState = transitionTable[stateValue][eventValue];
        this.score += actionTable[stateValue][eventValue];
    }

    public int getScore() {
        return score;
    }

    public State getState() {
        return currentState;
    }
}

狀態(tài)機實現(xiàn)方式三:狀態(tài)模式

在查表法的代碼實現(xiàn)中,事件觸發(fā)的動作只能是簡單的積分加減,所以,我們用一個 int 類型的二維數(shù)組 actionTable 就能表示,二維數(shù)組中的值表示積分的加減值。但是,如果要執(zhí)行的動作并非這么簡單,而是一系列復(fù)雜的邏輯操作(比如加減積分、寫數(shù)據(jù)庫,還有可能發(fā)送消息通知等等),我們就沒法用如此簡單的二維數(shù)組來表示了。也就是說,查表法的實現(xiàn)方式有一定的局限性。

雖然分支邏輯的實現(xiàn)方式不存在這個問題,但它又存在前面講到的其他問題,比如分支判斷邏輯較多,導(dǎo)致代碼的可讀性和可維護(hù)性不好等。實際上,對于分支邏輯法存在的問題,可以使用狀態(tài)模式來解決。

狀態(tài)模式通過將事件觸發(fā)的狀態(tài)轉(zhuǎn)移和動作執(zhí)行,拆分到不同的類中,來避免分支判斷邏輯。我們還是結(jié)合代碼來理解這句話。

其中,IMario 是狀態(tài)的接口,定義了所有事件。SmallMario、SuperMario、CapeMario、FireMarioIMario 接口的實現(xiàn)類,分別對應(yīng)狀態(tài)機種的 4 個狀態(tài)。原來所有的狀態(tài)轉(zhuǎn)移和動作執(zhí)行的代碼邏輯,都集中在 MarioStateMachine 中,現(xiàn)在,這些代碼被拆分到了這 4 個狀態(tài)類中。

public interface IMario {
    State getName();
    // 以下是定義的事件
    void obtainMushRoom();
    void obtainCape();
    void obtainFireFlower();
    void meetMonster();
}

public class SmallMario implements IMario {
    private MarioStateMachine stateMachine;

    public SmallMario(MarioStateMachine stateMachine) {
        this.stateMachine = stateMachine;
    }

    @Override
    public State getName() {
        return State.SMALL;
    }

    @Override
    public void obtainMushRoom() {
        stateMachine.setCurrentState(new SuperMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 100);
    }

    @Override
    public void obtainCape() {
        stateMachine.setCurrentState(new CapeMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 200);
    }

    @Override
    public void obtainFireFlower() {
        stateMachine.setCurrentState(new FireMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster() {
        // do nothing...
    }
}

public class SuperMario implements IMario {
    private MarioStateMachine stateMachine;

    public SuperMario(MarioStateMachine stateMachine) {
        this.stateMachine = stateMachine;
    }

    @Override
    public State getName() {
        return State.SUPER;
    }


    @Override
    public void obtainMushRoom() {
        // do nothing...
    }

    @Override
    public void obtainCape() {
        stateMachine.setCurrentState(new CapeMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 200);
    }

    @Override
    public void obtainFireFlower() {
        stateMachine.setCurrentState(new FireMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster() {
        stateMachine.setCurrentState(new SmallMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() - 100);
    }
}

public class CapeMario implements IMario {
    private MarioStateMachine stateMachine;

    public CapeMario(MarioStateMachine stateMachine) {
        this.stateMachine = stateMachine;
    }

    @Override
    public State getName() {
        return State.CAPE;
    }

    @Override
    public void obtainMushRoom() {
        // do nothing...
    }

    @Override
    public void obtainCape() {
        // do nothing...
    }

    @Override
    public void obtainFireFlower() {
        stateMachine.setCurrentState(new FireMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster() {
        stateMachine.setCurrentState(new SmallMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() - 200);
    }
}

public class FireMario implements IMario {
    private MarioStateMachine stateMachine;

    public FireMario(MarioStateMachine stateMachine) {
        this.stateMachine = stateMachine;
    }

    @Override
    public State getName() {
        return State.FIRE;
    }


    @Override
    public void obtainMushRoom() {
        // do nothing...
    }

    @Override
    public void obtainCape() {
        // do nothing...
    }

    @Override
    public void obtainFireFlower() {
        // do nothing...
    }

    @Override
    public void meetMonster() {
        stateMachine.setCurrentState(new SmallMario(stateMachine));
        stateMachine.setScore(stateMachine.getScore() - 300);
    }
}

public class MarioStateMachine {
    private int score;
    private IMario currentState; // 不在使用枚舉表示狀態(tài)

    public MarioStateMachine() {
        this.score = 0;
        this.currentState = new SmallMario(this);
    }

    public void obtainMushRoom() {
        currentState.obtainMushRoom();
    }

    public void obtainCape() {
        currentState.obtainCape();
    }

    public void obtainFireFlower() {
        currentState.obtainFireFlower();
    }

    public void meetMonster() {
        currentState.meetMonster();
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public void setCurrentState(IMario currentState) {
        this.currentState = currentState;
    }

    public IMario getState() {
        return currentState;
    }
}

上面的代碼實現(xiàn)不難看懂,只需要注意一點,即 MarioStateMachine 和各個狀態(tài)類之間是雙向依賴關(guān)系。 MarioStateMachine 依賴各個類是理所當(dāng)然的,但是反過來,各個狀態(tài)類為什么要依賴 MarioStateMachine 呢? 這是因為,各個狀態(tài)類需要更新 MarioStateMachine 中的屬性, scorecurrentState。

實際上,上面的代碼還可以繼續(xù)優(yōu)化,可以將狀態(tài)類設(shè)置成單例,比較狀態(tài)類中不包含任何成員變量。但是,當(dāng)狀態(tài)類設(shè)計成單例之后,就無法通過構(gòu)造函數(shù)來傳遞 MarioStateMachine 了,而狀態(tài)類又要依賴 MarioStateMachine ,那該如何解決呢?

實際上,在《創(chuàng)建型:2.單例模式(中):為什么不推薦使用單例模式?又有何替代方案?》中,提到過集中解決方法,你可以回過頭去查看下。在這里,可以通過函數(shù)參數(shù)將 MarioStateMachine 傳遞進(jìn)狀態(tài)類。根據(jù)這個設(shè)計思路,對上面的代碼進(jìn)行重構(gòu)。重構(gòu)之后的代碼如下所示:

public interface IMario {
    State getName();
    // 以下是定義的事件
    void obtainMushRoom(MarioStateMachine stateMachine);
    void obtainCape(MarioStateMachine stateMachine);
    void obtainFireFlower(MarioStateMachine stateMachine);
    void meetMonster(MarioStateMachine stateMachine);
}

public class SmallMario implements IMario {
    private static final SmallMario instance = new SmallMario();
    private SmallMario() {
    }
    public static SmallMario getInstance() {
        return instance;
    }

    @Override
    public State getName() {
        return State.SMALL;
    }

    @Override
    public void obtainMushRoom(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(SuperMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 100);
    }

    @Override
    public void obtainCape(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(CapeMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 200);
    }

    @Override
    public void obtainFireFlower(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(FireMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster(MarioStateMachine stateMachine) {
        // do nothing...
    }
}

public class SuperMario implements IMario {
    private static final SuperMario instance = new SuperMario();
    private SuperMario() {
    }
    public static SuperMario getInstance() {
        return instance;
    }

    @Override
    public State getName() {
        return State.SUPER;
    }


    @Override
    public void obtainMushRoom(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void obtainCape(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(CapeMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 200);
    }

    @Override
    public void obtainFireFlower(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(FireMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(SmallMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() - 100);
    }
}

public class CapeMario implements IMario {
    private static final CapeMario instance = new CapeMario();
    private CapeMario() {
    }
    public static CapeMario getInstance() {
        return instance;
    }

    @Override
    public State getName() {
        return State.CAPE;
    }

    @Override
    public void obtainMushRoom(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void obtainCape(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void obtainFireFlower(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(FireMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() + 300);
    }

    @Override
    public void meetMonster(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(SmallMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() - 200);
    }
}

public class FireMario implements IMario {
    private static final FireMario instance = new FireMario();
    private FireMario() {
    }
    public static FireMario getInstance() {
        return instance;
    }

    @Override
    public State getName() {
        return State.FIRE;
    }


    @Override
    public void obtainMushRoom(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void obtainCape(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void obtainFireFlower(MarioStateMachine stateMachine) {
        // do nothing...
    }

    @Override
    public void meetMonster(MarioStateMachine stateMachine) {
        stateMachine.setCurrentState(SmallMario.getInstance());
        stateMachine.setScore(stateMachine.getScore() - 300);
    }
}

public class MarioStateMachine {
    private int score;
    private IMario currentState; // 不在使用枚舉表示狀態(tài)

    public MarioStateMachine() {
        this.score = 0;
        this.currentState = SmallMario.getInstance();
    }

    public void obtainMushRoom() {
        currentState.obtainMushRoom(this);
    }

    public void obtainCape() {
        currentState.obtainCape(this);
    }

    public void obtainFireFlower() {
        currentState.obtainFireFlower(this);
    }

    public void meetMonster() {
        currentState.meetMonster(this);
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public void setCurrentState(IMario currentState) {
        this.currentState = currentState;
    }

    public IMario getState() {
        return currentState;
    }
}

實際上,像游戲這種比較復(fù)雜的狀態(tài)機,包含的狀態(tài)比較多,優(yōu)先推薦使用查表法,而狀態(tài)模式會引入非常多的狀態(tài)類,會導(dǎo)致代碼比較難維護(hù)。

相反,像電商下單、外賣下單這種類型的狀態(tài)機,它們的狀態(tài)并不多,狀態(tài)轉(zhuǎn)移也比較簡單,但事件觸發(fā)執(zhí)行的動作包含的業(yè)務(wù)邏輯可能會比較復(fù)雜,所以更加推薦使用狀態(tài)模式來實現(xiàn)。

總結(jié)

本章講解了狀態(tài)模式。雖然網(wǎng)上有各種各樣的狀態(tài)模式,但是你只要記住狀態(tài)模式是狀態(tài)機的一種實現(xiàn)方式即可。

狀態(tài)機又叫有限狀態(tài)機,它由3部分組成:狀態(tài)、事件、動作。

  • 其中事件也稱為轉(zhuǎn)移條件。
  • 事件觸發(fā)狀態(tài)的轉(zhuǎn)移及動作的執(zhí)行。
  • 不過動作不是必須的,也可能只轉(zhuǎn)移狀態(tài),不執(zhí)行任何動作。

針對狀態(tài)機,本章總結(jié)了三種實現(xiàn)方式。文章來源地址http://www.zghlxwxcb.cn/news/detail-846343.html

  • 第一種實現(xiàn)方式叫分支邏輯法。利用 if-else 或 switch-case 分支邏輯,參照狀態(tài)轉(zhuǎn)移圖,將每個狀態(tài)轉(zhuǎn)移原模原樣的直譯成代碼。對于簡單的狀態(tài)機來說,這種實現(xiàn)方式最簡單、最直接,是首選。
  • 第二種實現(xiàn)方式叫查表法。對于狀態(tài)很多、狀態(tài)轉(zhuǎn)移比較復(fù)雜的狀態(tài)機來說,查表法比較合適。通過二維素組來表示狀態(tài)轉(zhuǎn)移圖,能極大地提高代碼的可讀性和可維護(hù)性。
  • 第三張實現(xiàn)方式叫狀態(tài)模式。對于狀態(tài)不多、狀態(tài)轉(zhuǎn)移也比較簡單,但事件觸發(fā)執(zhí)行的動作包含的業(yè)務(wù)邏輯可能比較復(fù)雜的狀態(tài)機來說,首選這種實現(xiàn)方式。

到了這里,關(guān)于設(shè)計模式學(xué)習(xí)筆記 - 設(shè)計模式與范式 -行為型:8.狀態(tài)模式:游戲、工作流引擎中常用的狀態(tài)機是如何實現(xiàn)的?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【設(shè)計模式與范式:行為型】61 | 策略模式(下):如何實現(xiàn)一個支持給不同大小文件排序的小程序?

    上一節(jié)課,我們主要介紹了策略模式的原理和實現(xiàn),以及如何利用策略模式來移除 if-else 或者 switch-case 分支判斷邏輯。今天,我們結(jié)合“給文件排序”這樣一個具體的例子,來詳細(xì)講一講策略模式的設(shè)計意圖和應(yīng)用場景。 除此之外,在今天的講解中,我還會通過一步一步地

    2024年02月10日
    瀏覽(19)
  • 行為型設(shè)計模式——狀態(tài)模式

    行為型設(shè)計模式——狀態(tài)模式

    狀態(tài)模式是比較簡單的設(shè)計模式,它的主要作用是減少代碼中大量的 if-else 或者 switch-case 等邏輯判斷(俗稱屎山)。它將每個狀態(tài)定義為一個類,而每個狀態(tài)類有自己對應(yīng)的方法,因此當(dāng)需要根據(jù)狀態(tài)執(zhí)行邏輯代碼時不需要寫大量的if-else判斷是哪個狀態(tài)然后執(zhí)行對應(yīng)的邏輯

    2024年02月02日
    瀏覽(30)
  • 設(shè)計模式行為型-狀態(tài)模式

    設(shè)計模式行為型-狀態(tài)模式

    狀態(tài)模式是一種行為型設(shè)計模式,用于處理對象在不同狀態(tài)下的行為變化。它將對象的行為封裝在不同狀態(tài)類中,通過狀態(tài)的切換實現(xiàn)不同行為的觸發(fā)。 本文將介紹狀態(tài)模式的基本概念、應(yīng)用場景以及優(yōu)勢與適用性。 實現(xiàn)具體狀態(tài)類 具體工作類: 上下文類包含狀態(tài)對象的引

    2024年02月10日
    瀏覽(25)
  • 設(shè)計模式行為型——狀態(tài)模式

    設(shè)計模式行為型——狀態(tài)模式

    ? 目錄 狀態(tài)模式的定義 狀態(tài)模式的實現(xiàn) 狀態(tài)模式角色 狀態(tài)模式類圖 狀態(tài)模式舉例 狀態(tài)模式代碼實現(xiàn) 狀態(tài)模式的特點 優(yōu)點 缺點 使用場景 注意事項 實際應(yīng)用 ? ? ? ?在軟件開發(fā)過程中,應(yīng)用程序中的部分對象可能會根據(jù)不同的情況做出不同的行為,把這種對象稱為有狀態(tài)

    2024年02月14日
    瀏覽(24)
  • 【設(shè)計模式與范式:行為型】69 | 訪問者模式(下):為什么支持雙分派的語言不需要訪問者模式?

    上一節(jié)課中,我們學(xué)習(xí)了訪問者模式的原理和實現(xiàn),并且還原了訪問者模式誕生的思維過程??傮w上來講,這個模式的代碼實現(xiàn)比較難,所以應(yīng)用場景并不多。從應(yīng)用開發(fā)的角度來說,它的確不是我們學(xué)習(xí)的重點。 不過,我們前面反復(fù)說過,學(xué)習(xí)我的專欄,并不只是讓你掌握

    2024年02月10日
    瀏覽(23)
  • 設(shè)計模式—行為型模式之狀態(tài)模式

    設(shè)計模式—行為型模式之狀態(tài)模式

    狀態(tài)(State)模式:對有狀態(tài)的對象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對象中,允許狀態(tài)對象在其內(nèi)部狀態(tài)發(fā)生改變時改變其行為。 狀態(tài)模式包含以下主要角色: 環(huán)境類(Context)角色:也稱為上下文,它定義了客戶端需要的接口,內(nèi)部維護(hù)一個當(dāng)前狀態(tài),并負(fù)責(zé)具

    2024年01月15日
    瀏覽(20)
  • 設(shè)計模式學(xué)習(xí)筆記 - 開源實戰(zhàn)三(下):借助Google Guava學(xué)習(xí)三大編程范式中的函數(shù)式編程

    現(xiàn)在主流的編程范式主要有三種,面向過程、面向?qū)ο蠛秃瘮?shù)式編程。在理論部分,已經(jīng)介紹了前面兩種編程范式。本章再講講剩下的編程范式,函數(shù)式編程。 函數(shù)式編程并非是一個很新的東西,早在 50 年前就已經(jīng)出現(xiàn)。近幾年,函數(shù)式編程越來越被人關(guān)注,出現(xiàn)了很多新

    2024年04月22日
    瀏覽(25)
  • 笨蛋學(xué)設(shè)計模式行為型模式-狀態(tài)模式【20】

    8.7.1概念 ? 狀態(tài)模式是指對象在運行時可以根據(jù)內(nèi)部狀態(tài)的不同而改變它們的行為,該模式將內(nèi)部狀態(tài)的行為封裝為不同的具體狀態(tài)類中,并將狀態(tài)轉(zhuǎn)換邏輯委托給這些狀態(tài)類來處理,當(dāng)對象的內(nèi)部狀態(tài)發(fā)生變化時,它會自動切換到對應(yīng)的狀態(tài)類,從而改變其行為。 8.7.2場景

    2024年01月23日
    瀏覽(21)
  • 【十五】設(shè)計模式~~~行為型模式~~~狀態(tài)模式(Java)

    【十五】設(shè)計模式~~~行為型模式~~~狀態(tài)模式(Java)

    【學(xué)習(xí)難度:★★★☆☆,使用頻率:★★★☆☆】 在很多情況下,一個對象的行為取決于一個或多個動態(tài)變化的屬性,這樣的屬性叫做狀態(tài),這樣的對象叫做有狀態(tài)的(stateful)對象,這樣的對象狀態(tài)是從事先定義好的一系列值中取出的。當(dāng)一個這樣的對象與外部事件產(chǎn)生互

    2024年02月07日
    瀏覽(17)
  • 【地鐵上的設(shè)計模式】--行為型模式:狀態(tài)模式

    什么是狀態(tài)模式 狀態(tài)模式是一種行為模式,它允許對象在其內(nèi)部狀態(tài)發(fā)生改變時改變其行為。在狀態(tài)模式中,將狀態(tài)定義為獨立的對象,并將對象在不同狀態(tài)下的行為委托給具有相應(yīng)行為的狀態(tài)對象。當(dāng)對象的狀態(tài)發(fā)生變化時,它將使用不同的狀態(tài)對象來執(zhí)行不同的操作,從

    2024年02月04日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包