cover

State 模式:行為依狀態切換

State 模式把每個狀態的行為拆成獨立類別,讓狀態轉換清楚且易於維護。

classDiagram
    class Order {
        -state : OrderState
        +setState(state) void
        +process() void
        +ship() void
        +complete() void
    }
    class OrderState {
        <<interface>>
        +process()* void
        +ship()* void
        +complete()* void
    }
    class PendingState {
        -order : Order
        +process() void
        +ship() void
        +complete() void
    }
    class ProcessingState {
        -order : Order
        +process() void
        +ship() void
        +complete() void
    }
    class ShippedState {
        -order : Order
        +process() void
        +ship() void
        +complete() void
    }
    Order o-- OrderState : 持有當前狀態
    OrderState <|.. PendingState
    OrderState <|.. ProcessingState
    OrderState <|.. ShippedState

使用情境

  1. 訂單處理:Pending → Processing → Shipped → Completed。
  2. 工作流程:審核流程依狀態決定可執行的動作。

實作範例

State 模式:訂單狀態流轉

class Order {
  constructor() {
    this.state = new PendingState(this);
  }
 
  setState(state) {
    this.state = state;
  }
 
  process() {
    this.state.process();
  }
 
  ship() {
    this.state.ship();
  }
 
  complete() {
    this.state.complete();
  }
}
 
class PendingState {
  constructor(order) {
    this.order = order;
  }
 
  process() {
    console.log('Processing order...');
    this.order.setState(new ProcessingState(this.order));
  }
 
  ship() {
    console.log('Cannot ship - order not processed yet');
  }
 
  complete() {
    console.log('Cannot complete - order not shipped yet');
  }
}
 
class ProcessingState {
  constructor(order) {
    this.order = order;
  }
 
  process() {
    console.log('Order already processing');
  }
 
  ship() {
    console.log('Shipping order...');
    this.order.setState(new ShippedState(this.order));
  }
 
  complete() {
    console.log('Cannot complete - order not shipped yet');
  }
}
 
class ShippedState {
  constructor(order) {
    this.order = order;
  }
 
  process() {
    console.log('Order already shipped');
  }
 
  ship() {
    console.log('Order already shipped');
  }
 
  complete() {
    console.log('Order completed!');
    this.order.setState(new CompletedState(this.order));
  }
}
 
const order = new Order();
order.process();
order.ship();
order.complete();

優點

  • 狀態轉換清楚
  • 狀態邏輯集中
  • 減少條件判斷

缺點

  • 類別數量增加

延伸閱讀