首頁>技術>

2020年已經進入倒計時了,大家立好的flag完成了嗎?2020實“鼠”不易,希望2021可以“牛”轉乾坤。

簡介

狀態模式是行為型設計模式的一種。其設計理念是當物件的內部狀態發生改變時,隨之改變其行為。狀態和行為之間是一一對應的。

該模式主要用於,物件的行為依賴於它的狀態,並且其行為是隨著狀態的改變而切換時。

狀態模式UML類圖

類圖講解

State:抽象狀態介面(也可以定義成抽象類),該介面封裝了所有狀態所對應的行為。ConcreteStateA/B:具體狀態類,該類實現了抽象狀態介面,會根據自身對應的狀態來實現介面中定義的方法,還有另一個功能是指明如何過渡到下一個狀態。Context:環境(上下文)角色,該類負責狀態的切換,還持有一個State例項,代表當前環境所處狀態。

案例講解

案例:透過狀態模式來實現自助售賣機的功能。

狀態介面

public interface State {  // 挑選商品  void choose();  // 付款  boolean payment();  // 分發商品  void dispenseCommodity();}

挑選商品狀態類

public class ChooseGoods implements State {  VendingMachine machine;  public ChooseGoods(VendingMachine machine) {    this.machine = machine;  }  @Override  public void choose() {    if (machine.getCount() > 0) {      System.out.println("商品挑選成功,請及時付款!");      machine.setState(machine.getPaymentState());    } else {      System.out.println("很遺憾,商品售罄了!");      machine.setState(machine.getEmptyState());    }  }  @Override  public boolean payment() {    System.out.println("請先挑選商品!");    return false;  }  @Override  public void dispenseCommodity() {    System.out.println("請先挑選商品!");  }}

付款狀態類

public class PaymentState implements State {  VendingMachine machine;  public PaymentState(VendingMachine machine) {    this.machine = machine;  }  @Override  public void choose() {    System.out.println("商品已選購完成請勿重複挑選");  }  @Override  public boolean payment() {    Random random = new Random();    int num = random.nextInt(10);    if(num % 2 == 0){      System.out.println("付款成功!");      machine.setState(machine.getDispenseCommodityState());      return true;    }    System.out.println("付款失敗,請重新支付!");    return false;  }  @Override  public void dispenseCommodity() {    System.out.println("請先完成支付!");  }}

商品售罄狀態類

public class EmptyState implements State {  VendingMachine machine;  public EmptyState(VendingMachine machine) {    this.machine = machine;  }  @Override  public void choose() {    System.out.println("對不起商品已售罄!");  }  @Override  public boolean payment() {    System.out.println("對不起商品已售罄!");    return false;  }  @Override  public void dispenseCommodity() {    System.out.println("對不起商品已售罄!");  }}

分發商品狀態類

public class DispenseCommodityState implements State {  VendingMachine machine;  public DispenseCommodityState(VendingMachine machine) {    this.machine = machine;  }  @Override  public void choose() {    System.out.println("請及時取走您的商品!");  }  @Override  public boolean payment() {    System.out.println("請及時取走您的商品!");    return false;  }  @Override  public void dispenseCommodity() {    System.out.println("請及時取走您的商品!");    machine.setState(machine.getChooseGoods());  }}

自動售貨機 => Context角色

public class VendingMachine {  // 表示當前狀態  private State state = null;  // 商品數量  private int count = 0;  private State chooseGoods = new ChooseGoods(this);  private State paymentState = new PaymentState(this);  private State dispenseCommodityState = new DispenseCommodityState(this);  private State emptyState = new EmptyState(this);  public VendingMachine(int count) {    this.count = count;    this.state = this.getChooseGoods();  }  // 購買商品  public void purchase() {    // 挑選商品    state.choose();    // 支付成功    if (state.payment()) {      // 分發商品      state.dispenseCommodity();    }  }    // 獲取商品後將商品減一  public int getCount() {    return count--;  }    // get和set方法 ... }

客戶端測試類

public class Client {  public static void main(String[] args) {    VendingMachine machine = new VendingMachine(1);    for (int i = 1; i < 4; i++) {      System.out.println("第" + i + "次購買。");      machine.purchase();    }  }}

執行結果

總結

1、狀態模式將每個狀態所對應的行為封裝到一個類中,大大提高了程式碼的可讀性。並且透過這樣的設計還可以消除多餘的if-else語句,方便程式碼的維護。

3、任何事情都有利弊,狀態模式也不例外。其最顯著的問題是,每個狀態都要對應一個類,當狀態過多時會產生大量的類,從而加大維護成本。

4、應用場景:當一個需求有很多狀態,並且狀態之間會進行轉換,不同狀態還對應不同的行為時就可以考慮使用“狀態模式”。

13
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • MFC繪圖操作