← Back to scenarios
ScenarioCatalog DB

Order state

Change order behavior as an order moves from pending to processing to shipped.

Problem

An order workflow must enforce state-specific actions and valid transitions without centralizing growing conditional logic for every order status in the order object.

Related patterns

Implementations

State

TypeScriptApplication

State in TypeScript

Changes an order’s behavior by delegating cancellation rules to its current lifecycle state.

TypeScript
interface OrderState {
  cancel(order: Order): void;
  name(): string;
}

class Order {
  constructor(private state: OrderState) {}

  setState(state: OrderState) {
    this.state = state;
  }

  cancel() {
    this.state.cancel(this);
  }

  printStatus() {
    console.log(`Order is ${this.state.name()}`);
  }
}

class PendingState implements OrderState {
  cancel(order: Order) {
    console.log("Cancelling pending order.");
    order.setState(new CancelledState());
  }

  name() {
    return "pending";
  }
}

class ShippedState implements OrderState {
  cancel() {
    console.log("Shipped orders cannot be cancelled.");
  }

  name() {
    return "shipped";
  }
}

class CancelledState implements OrderState {
  cancel() {
    console.log("Order is already cancelled.");
  }

  name() {
    return "cancelled";
  }
}

const order = new Order(new PendingState());

order.printStatus();
order.cancel();
order.printStatus();

order.setState(new ShippedState());
order.cancel();

Associated technologies