1. 程式人生 > 其它 >kubernetes 【排程和驅逐】【2】kube-scheduler排程器

kubernetes 【排程和驅逐】【2】kube-scheduler排程器

技術標籤:學習資料設計模式

設計模式

本系列文章均是博主原創,意在記錄學習上的知識,同時一起分享學習心得。

24種設計模式


文章目錄


前言

本章介紹狀態模式的定義、實現方式和使用場景。


一、定義

有限狀態機,英文翻譯是Finite State Machine,縮寫FSM,簡稱為狀態機。狀態機有3個組成部分:狀態(State)、事件(Event)、動作(Action)。其中,事件也稱為轉移條件(Transaction Condition)。事件觸發狀態的轉移及動作的執行。不過,動作不是必須的,也可能只轉移狀態,不執行任何動作。

二、實現方式

狀態機的實現方式:

  • 定義一個狀態列舉類,確定有多少種狀態。
  • 定義一個狀態類介面,並定義好所有事件方法、獲取狀態的方法。
  • 定義一個狀態機類,狀態機定義成員狀態變數。
  • 實現狀態類介面。

程式碼如下(示例):

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

    private int value;

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

    public int getValue() {
        return
value; } }
public interface IMario {
    State getName();
    void obtainMushRoom(MarioStateMachine marioStateMachine);
    void obtainCape(MarioStateMachine marioStateMachine);
    void obtainFireFlower(MarioStateMachine marioStateMachine);
    void meetMonster(MarioStateMachine marioStateMachine)
; }
public class MarioStateMachine {
    private int score;
    private IMario currentState;

    @Override
    public String toString() {
        return "MarioStateMachine{" +
                "score=" + score +
                ", currentState=" + currentState.getName().getValue() +
                '}';
    }

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

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

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

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

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

    public int getScore() {
        return this.score;
    }

    public State getCurrentState() {
        return this.currentState.getName();
    }

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

    public void setCurrentState(IMario mario) {
        this.currentState = mario;
    }
}
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 marioStateMachine) {
        marioStateMachine.setCurrentState(SuperMario.getInstance());
        marioStateMachine.setScore(marioStateMachine.getScore() + 100);
    }

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

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

    @Override
    public void meetMonster(MarioStateMachine marioStateMachine) {
        // 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 marioStateMachine) {
        // do nothing
    }

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

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

    @Override
    public void meetMonster(MarioStateMachine marioStateMachine) {
        marioStateMachine.setCurrentState(SmallMario.getInstance());
        marioStateMachine.setScore(marioStateMachine.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 marioStateMachine) {
        // do nothing
    }

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

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

    @Override
    public void meetMonster(MarioStateMachine marioStateMachine) {
        marioStateMachine.setCurrentState(SmallMario.getInstance());
        marioStateMachine.setScore(marioStateMachine.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 marioStateMachine) {
        // do nothing
    }

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

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

    @Override
    public void meetMonster(MarioStateMachine marioStateMachine) {
        marioStateMachine.setCurrentState(SmallMario.getInstance());
        marioStateMachine.setScore(marioStateMachine.getScore() - 300);
    }
}
@Test
public void testStateMachine() {
    MarioStateMachine marioStateMachine = new MarioStateMachine();
    System.out.println("初始狀態:" + marioStateMachine);
    marioStateMachine.obtainMushRoom();
    System.out.println("吃到蘑菇:" +marioStateMachine);
    marioStateMachine.obtainFireFlower();
    System.out.println("吃到火焰:" +marioStateMachine);
    marioStateMachine.meetMonster();
    System.out.println("遇到怪物:" +marioStateMachine);
    marioStateMachine.obtainCape();
    System.out.println("吃到斗篷:" +marioStateMachine);
}

在這裡插入圖片描述

三、使用場景

針對狀態機,其實一共有3種實現方式,本文只描述了其中一種。

  • 第一種實現方式叫分支邏輯法。利用if-else分支邏輯,參照狀態轉移圖,將每一個狀態轉移原模原樣地直譯成程式碼。對於簡單的狀態機來說,這種實現方式最簡單、最直接,是首選。
  • 第二種實現方式叫查表法。對於狀態很多、狀態轉移比較複雜的狀態機來說,查表法比較合適。通過二維陣列來表示狀態轉移圖,能極大地提高程式碼地可讀性和可維護性。
  • 第三種實現方式叫狀態模式。對於狀態不多、狀態轉移也比較簡單,但事件觸發執行地動作包含地業務邏輯可能比較複雜的狀態機來說,我們首先這種實現方式。

總結

實際上,像遊戲這種比較複雜的狀態機,包含的狀態比較多,優先推薦使用查表法。像電商下單、外賣下單這種型別的狀態機,它們的狀態並不多,狀態轉移也比較簡單,但事件觸發執行的動作包含的業務邏輯可能比較複雜,所以,更加推薦使用狀態模式來實現。