kubernetes 【排程和驅逐】【2】kube-scheduler排程器
阿新 • • 發佈:2021-01-26
設計模式
本系列文章均是博主原創,意在記錄學習上的知識,同時一起分享學習心得。文章目錄
前言
本章介紹狀態模式的定義、實現方式和使用場景。
一、定義
有限狀態機,英文翻譯是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分支邏輯,參照狀態轉移圖,將每一個狀態轉移原模原樣地直譯成程式碼。對於簡單的狀態機來說,這種實現方式最簡單、最直接,是首選。
- 第二種實現方式叫查表法。對於狀態很多、狀態轉移比較複雜的狀態機來說,查表法比較合適。通過二維陣列來表示狀態轉移圖,能極大地提高程式碼地可讀性和可維護性。
- 第三種實現方式叫狀態模式。對於狀態不多、狀態轉移也比較簡單,但事件觸發執行地動作包含地業務邏輯可能比較複雜的狀態機來說,我們首先這種實現方式。
總結
實際上,像遊戲這種比較複雜的狀態機,包含的狀態比較多,優先推薦使用查表法。像電商下單、外賣下單這種型別的狀態機,它們的狀態並不多,狀態轉移也比較簡單,但事件觸發執行的動作包含的業務邏輯可能比較複雜,所以,更加推薦使用狀態模式來實現。