状态模式核心概念

  1. 状态模式 (State Pattern):是一种行为型设计模式,核心思想是:将对象的不同状态封装成独立的状态类,让对象的行为随着其状态的改变而改变,而非通过大量的 if/elseswitch 语句控制
  2. 类图:
  3. 实现代码:
    // 1. 抽象状态类(对应类图中的 State)
    abstract class OrderState {
      /**
       * 处理当前状态的核心行为
       * @param context 上下文(订单对象),用于状态切换
       */
      abstract handle(context: OrderContext): void;
    
      /**
       * 获取状态名称(便于调试/展示)
       */
      abstract getName(): string;
    }
    
    // 2. 具体状态类:待支付(对应类图中的 StateA)
    class PendingPaymentState extends OrderState {
      handle(context: OrderContext): void {
        console.log(`当前订单状态:${this.getName()} → 执行支付逻辑`);
        // 支付成功后,切换到“已支付”状态
        context.setState(new PaidState());
      }
    
      getName(): string {
        return "待支付";
      }
    }
    
    // 3. 具体状态类:已支付(对应类图中的 StateB)
    class PaidState extends OrderState {
      handle(context: OrderContext): void {
        console.log(`当前订单状态:${this.getName()} → 执行发货/确认收货逻辑`);
        // 确认收货后,切换到“已完成”状态
        context.setState(new CompletedState());
      }
    
      getName(): string {
        return "已支付";
      }
    }
    
    // 4. 具体状态类:已完成(对应类图中的 StateC)
    class CompletedState extends OrderState {
      handle(context: OrderContext): void {
        console.log(`当前订单状态:${this.getName()} → 订单已结束,无后续操作`);
        // 已完成状态无需切换
      }
    
      getName(): string {
        return "已完成";
      }
    }
    
    // 5. 上下文类:订单(对应类图中的 Context)
    class OrderContext {
      private state: OrderState; // 持有当前状态引用
    
      constructor() {
        // 订单初始状态:待支付
        this.state = new PendingPaymentState();
      }
    
      /**
       * 切换状态(核心方法)
       * @param newState 新状态
       */
      setState(newState: OrderState): void {
        console.log(`状态切换:${this.state.getName()} → ${newState.getName()}`);
        this.state = newState;
      }
    
      /**
       * 对外暴露的统一操作入口(触发当前状态的行为)
       */
      execute(): void {
        this.state.handle(this);
      }
    
      /**
       * 获取当前状态名称(便于外部查询)
       */
      getCurrentStateName(): string {
        return this.state.getName();
      }
    }
    
    // ==================== 测试代码 ====================
    const order = new OrderContext();
    
    // 第一次执行:待支付 → 已支付
    order.execute();
    // 输出:
    // 当前订单状态:待支付 → 执行支付逻辑
    // 状态切换:待支付 → 已支付
    
    // 第二次执行:已支付 → 已完成
    order.execute();
    // 输出:
    // 当前订单状态:已支付 → 执行发货/确认收货逻辑
    // 状态切换:已支付 → 已完成
    
    // 第三次执行:已完成(无状态切换)
    order.execute();
    // 输出:
    // 当前订单状态:已完成 → 订单已结束,无后续操作
    
    console.log("最终订单状态:", order.getCurrentStateName());
    // 输出:最终订单状态:已完成
    

状态模式的常用场景

表单状态流转

  1. 场景:表单 (草稿 / 编辑中 / 已提交 / 审核中 / 审核通过 / 审核驳回)

  2. 示例:编辑中状态下可提交表单,提交后切换到审核中;审核驳回后切回编辑中,审核通过后切到已完成;

    // 抽象状态类
    abstract class FormState {
      abstract handle(context: FormContext): void;
      abstract getName(): string;
    }
    
    // 具体状态:草稿
    class DraftState extends FormState {
      handle(context: FormContext) {
        console.log(`[表单] ${this.getName()} → 进入编辑模式`);
        context.setState(new EditingState());
      }
      getName() { return "草稿"; }
    }
    
    // 具体状态:编辑中
    class EditingState extends FormState {
      handle(context: FormContext) {
        console.log(`[表单] ${this.getName()} → 提交表单`);
        context.setState(new SubmittedState());
      }
      getName() { return "编辑中"; }
    }
    
    // 具体状态:已提交
    class SubmittedState extends FormState {
      handle(context: FormContext, isApproved: boolean = true) {
        console.log(`[表单] ${this.getName()} → 审核中...`);
        // 审核结果分支
        context.setState(isApproved ? new ApprovedState() : new RejectedState());
      }
      getName() { return "已提交"; }
    }
    
    // 具体状态:审核通过
    class ApprovedState extends FormState {
      handle(context: FormContext) {
        console.log(`[表单] ${this.getName()} → 表单生效,流程结束`);
      }
      getName() { return "审核通过"; }
    }
    
    // 具体状态:审核驳回
    class RejectedState extends FormState {
      handle(context: FormContext) {
        console.log(`[表单] ${this.getName()} → 退回编辑模式`);
        context.setState(new EditingState());
      }
      getName() { return "审核驳回"; }
    }
    
    // 表单上下文
    class FormContext {
      private state: FormState;
    
      constructor() {
        this.state = new DraftState(); // 初始状态:草稿
      }
    
      setState(newState: FormState) {
        console.log(`状态切换:${this.state.getName()} → ${newState.getName()}`);
        this.state = newState;
      }
    
      // 通用操作入口
      execute(isApproved?: boolean) {
        if (this.state instanceof SubmittedState) {
          (this.state as SubmittedState).handle(this, isApproved);
        } else {
          this.state.handle(this);
        }
      }
    
      getCurrentState() {
        return this.state.getName();
      }
    }
    
    // 测试
    const form = new FormContext();
    form.execute(); // 草稿 → 编辑中
    form.execute(); // 编辑中 → 已提交
    form.execute(true); // 已提交 → 审核通过
    // form.execute(false); // 可测试驳回流程
    console.log("最终状态:", form.getCurrentState());
    

播放器状态控制

  1. 场景:音频 / 视频播放器 (播放 / 暂停 / 停止 / 加载中 / 出错)

  2. 优势:不同状态下的行为隔离 (如 “暂停” 状态下点击播放按钮,执行 “恢复播放” 逻辑;“停止” 状态下点击播放,执行 “重新播放” 逻辑)

    // 抽象状态类
    abstract class PlayerState {
      abstract handle(context: PlayerContext): void;
      abstract getName(): string;
    }
    
    // 具体状态:加载中
    class LoadingState extends PlayerState {
      handle(context: PlayerContext) {
        console.log(`[播放器] ${this.getName()} → 资源加载完成`);
        context.setState(new PlayingState());
      }
      getName() { return "加载中"; }
    }
    
    // 具体状态:播放中
    class PlayingState extends PlayerState {
      handle(context: PlayerContext) {
        console.log(`[播放器] ${this.getName()} → 暂停播放`);
        context.setState(new PausedState());
      }
      getName() { return "播放中"; }
    }
    
    // 具体状态:暂停
    class PausedState extends PlayerState {
      handle(context: PlayerContext) {
        console.log(`[播放器] ${this.getName()} → 继续播放`);
        context.setState(new PlayingState());
      }
      getName() { return "暂停"; }
    }
    
    // 具体状态:停止
    class StoppedState extends PlayerState {
      handle(context: PlayerContext) {
        console.log(`[播放器] ${this.getName()} → 重新加载`);
        context.setState(new LoadingState());
      }
      getName() { return "停止"; }
    }
    
    // 播放器上下文
    class PlayerContext {
      private state: PlayerState;
    
      constructor() {
        this.state = new LoadingState(); // 初始加载
      }
    
      setState(newState: PlayerState) {
        console.log(`状态切换:${this.state.getName()} → ${newState.getName()}`);
        this.state = newState;
      }
    
      // 统一操作:点击播放/暂停/停止按钮
      toggle() {
        this.state.handle(this);
      }
    
      // 强制停止
      stop() {
        console.log(`[播放器] 强制停止`);
        this.setState(new StoppedState());
      }
    
      getCurrentState() {
        return this.state.getName();
      }
    }
    
    // 测试
    const player = new PlayerContext();
    player.toggle(); // 加载中 → 播放中
    player.toggle(); // 播放中 → 暂停
    player.toggle(); // 暂停 → 播放中
    player.stop();   // 强制停止 → 停止
    player.toggle(); // 停止 → 加载中
    

页面 / 组件生命周期状态

  1. 场景:复杂组件 (如弹窗:关闭 / 打开中 / 已打开 / 关闭中;分页组件:加载中 / 加载完成 / 加载失败)

  2. 优势:避免在组件中用大量变量 (isLoading/isOpen/isError) 控制行为,状态切换逻辑更清晰;

    // 抽象状态类
    abstract class ComponentState {
      abstract handle(context: ComponentContext): void;
      abstract getName(): string;
    }
    
    // 具体状态:关闭
    class ClosedState extends ComponentState {
      handle(context: ComponentContext) {
        console.log(`[弹窗] ${this.getName()} → 执行打开动画`);
        context.setState(new OpeningState());
      }
      getName() { return "关闭"; }
    }
    
    // 具体状态:打开中(动画执行)
    class OpeningState extends ComponentState {
      handle(context: ComponentContext) {
        console.log(`[弹窗] ${this.getName()} → 动画完成,弹窗打开`);
        context.setState(new OpenedState());
      }
      getName() { return "打开中"; }
    }
    
    // 具体状态:已打开
    class OpenedState extends ComponentState {
      handle(context: ComponentContext) {
        console.log(`[弹窗] ${this.getName()} → 执行关闭动画`);
        context.setState(new ClosingState());
      }
      getName() { return "已打开"; }
    }
    
    // 具体状态:关闭中(动画执行)
    class ClosingState extends ComponentState {
      handle(context: ComponentContext) {
        console.log(`[弹窗] ${this.getName()} → 动画完成,弹窗关闭`);
        context.setState(new ClosedState());
      }
      getName() { return "关闭中"; }
    }
    
    // 组件上下文(弹窗)
    class ComponentContext {
      private state: ComponentState;
    
      constructor() {
        this.state = new ClosedState(); // 初始关闭
      }
    
      setState(newState: ComponentState) {
        console.log(`状态切换:${this.state.getName()} → ${newState.getName()}`);
        this.state = newState;
      }
    
      // 触发组件状态变更(打开/关闭)
      trigger() {
        this.state.handle(this);
      }
    
      getCurrentState() {
        return this.state.getName();
      }
    }
    
    // 测试
    const modal = new ComponentContext();
    modal.trigger(); // 关闭 → 打开中
    modal.trigger(); // 打开中 → 已打开
    modal.trigger(); // 已打开 → 关闭中
    modal.trigger(); // 关闭中 → 关闭
    

游戏角色状态(小游戏 / 互动场景)

  1. 场景:游戏角色 (站立 / 行走 / 跳跃 / 攻击 / 受伤 / 死亡)

  2. 优势:不同状态下的行为独立 (如 “受伤” 状态下无法攻击,“死亡” 状态下所有操作无效)

    // 抽象状态类
    abstract class RoleState {
      abstract handle(context: RoleContext): void;
      abstract getName(): string;
    }
    
    // 具体状态:站立
    class IdleState extends RoleState {
      handle(context: RoleContext) {
        console.log(`[角色] ${this.getName()} → 开始行走`);
        context.setState(new WalkingState());
      }
      getName() { return "站立"; }
    }
    
    // 具体状态:行走
    class WalkingState extends RoleState {
      handle(context: RoleContext) {
        console.log(`[角色] ${this.getName()} → 触发跳跃`);
        context.setState(new JumpingState());
      }
      getName() { return "行走"; }
    }
    
    // 具体状态:跳跃
    class JumpingState extends RoleState {
      handle(context: RoleContext) {
        console.log(`[角色] ${this.getName()} → 落地受伤`);
        context.setState(new HurtState());
      }
      getName() { return "跳跃"; }
    }
    
    // 具体状态:受伤
    class HurtState extends RoleState {
      handle(context: RoleContext) {
        console.log(`[角色] ${this.getName()} → 血量为0,死亡`);
        context.setState(new DeadState());
      }
      getName() { return "受伤"; }
    }
    
    // 具体状态:死亡
    class DeadState extends RoleState {
      handle(context: RoleContext) {
        console.log(`[角色] ${this.getName()} → 无法执行任何操作`);
        // 死亡状态无切换
      }
      getName() { return "死亡"; }
    }
    
    // 角色上下文
    class RoleContext {
      private state: RoleState;
      public hp: number = 100; // 血量(模拟状态判断条件)
    
      constructor() {
        this.state = new IdleState(); // 初始站立
      }
    
      setState(newState: RoleState) {
        console.log(`状态切换:${this.state.getName()} → ${newState.getName()}`);
        this.state = newState;
        // 受伤时扣血
        if (newState instanceof HurtState) this.hp -= 100;
      }
    
      // 执行角色动作(移动/跳跃等)
      doAction() {
        if (this.state instanceof DeadState) {
          console.log("[角色] 已死亡,动作无效");
          return;
        }
        this.state.handle(this);
      }
    
      getCurrentState() {
        return this.state.getName();
      }
    }
    
    // 测试
    const role = new RoleContext();
    role.doAction(); // 站立 → 行走
    role.doAction(); // 行走 → 跳跃
    role.doAction(); // 跳跃 → 受伤(血量归零)
    role.doAction(); // 受伤 → 死亡
    role.doAction(); // 死亡 → 动作无效
    console.log("角色血量:", role.hp);
    console.log("最终状态:", role.getCurrentState());
    

订单 / 交易状态管理(最典型)

  1. 以「电商订单全生命周期」为场景 (覆盖下单→支付→履约→售后→完结全流程),这个场景是前端最复杂的状态流转场景之一,包含:

    1. 多分支流转 (支付成功 / 失败、发货 / 取消发货、售后通过 / 驳回)
    2. 状态依赖 (如 “申请售后” 必须在 “已发货” 之后)
    3. 历史状态回溯 (取消订单后可重新下单)
    4. 禁止流转规则 (如 “已完结” 订单不可操作)
  2. 图解:

  3. 实现代码:

    // 订单状态枚举(覆盖全生命周期)
    type OrderStatus = 
      | "INIT"        // 初始(未下单)
      | "PENDING_PAY" // 待支付
      | "PAY_SUCCESS" // 支付成功
      | "PAY_FAILED"  // 支付失败
      | "PENDING_SEND"// 待发货
      | "SHIPPED"     // 已发货
      | "RECEIVED"    // 已收货
      | "REFUND_APPLY"// 申请售后
      | "REFUND_PASS" // 售后通过
      | "REFUND_REJECT"// 售后驳回
      | "COMPLETED"   // 订单完结
      | "CANCELED";   // 订单取消
    
    // 订单上下文(包含订单基础信息+状态控制)
    class OrderContext {
      public orderId: string;
      public amount: number;
      public payAmount: number = 0;
      public isPaid: boolean = false;
      public historyStatus: OrderStatus[] = []; // 历史状态回溯
      private state: OrderState; // 当前状态
    
      constructor(orderId: string, amount: number) {
        this.orderId = orderId;
        this.amount = amount;
        this.state = new InitState(); // 初始状态
        this.recordHistory(this.state.getStatus());
      }
    
      // 切换状态
      setState(newState: OrderState): void {
        const oldStatus = this.state.getStatus();
        const newStatus = newState.getStatus();
        console.log(`[订单${this.orderId}] 状态变更:${oldStatus} → ${newStatus}`);
        this.state = newState;
        this.recordHistory(newStatus);
      }
    
      // 记录历史状态
      private recordHistory(status: OrderStatus): void {
        if (!this.historyStatus.includes(status)) {
          this.historyStatus.push(status);
        }
      }
    
      // 执行状态行为(对外统一入口)
      execute(action: { type: string; payload?: any }): void {
        this.state.handle(this, action);
      }
    
      // 获取当前状态
      getCurrentStatus(): OrderStatus {
        return this.state.getStatus();
      }
    
      // 获取历史状态
      getHistoryStatus(): OrderStatus[] {
        return [...this.historyStatus];
      }
    }
    
    // 抽象状态类(定义核心行为)
    abstract class OrderState {
      // 获取当前状态标识
      abstract getStatus(): OrderStatus;
    
      /**
       * 处理状态行为(核心方法)
       * @param context 订单上下文
       * @param action 操作行为(类型+参数)
       */
      abstract handle(context: OrderContext, action: { type: string; payload?: any }): void;
    
      /**
       * 校验状态流转是否合法(通用方法)
       * @param context 订单上下文
       * @param allowStatus 允许流转的前置状态
       * @returns 是否合法
       */
      protected checkAllow(context: OrderContext, allowStatus: OrderStatus[]): boolean {
        const current = context.getCurrentStatus();
        if (!allowStatus.includes(current)) {
          console.error(`[订单${context.orderId}] 非法操作:当前状态${current},仅允许${allowStatus.join("/")}状态执行`);
          return false;
        }
        return true;
      }
    }
    
    // ==================== 具体状态实现 ====================
    
    // 1. 初始状态(未下单)
    class InitState extends OrderState {
      getStatus(): OrderStatus {
        return "INIT";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "CREATE_ORDER": // 创建订单
            context.setState(new PendingPayState());
            break;
          default:
            console.error(`[订单${context.orderId}] 初始状态不支持${action.type}操作`);
        }
      }
    }
    
    // 2. 待支付状态
    class PendingPayState extends OrderState {
      getStatus(): OrderStatus {
        return "PENDING_PAY";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "PAY": // 支付操作
            const payAmount = action.payload?.amount || 0;
            if (payAmount < context.amount) {
              console.error(`[订单${context.orderId}] 支付金额不足:需支付${context.amount},实际支付${payAmount}`);
              context.setState(new PayFailedState());
              return;
            }
            context.payAmount = payAmount;
            context.isPaid = true;
            context.setState(new PaySuccessState());
            break;
          case "CANCEL_ORDER": // 取消订单
            context.setState(new CanceledState());
            break;
          default:
            console.error(`[订单${context.orderId}] 待支付状态不支持${action.type}操作`);
        }
      }
    }
    
    // 3. 支付成功状态
    class PaySuccessState extends OrderState {
      getStatus(): OrderStatus {
        return "PAY_SUCCESS";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "SEND_GOODS": // 商家发货
            context.setState(new PendingSendState());
            break;
          case "CANCEL_ORDER": // 取消订单(支付成功后仅1小时内可取消)
            const canCancel = action.payload?.within1Hour || false;
            if (canCancel) {
              context.setState(new CanceledState());
            } else {
              console.error(`[订单${context.orderId}] 支付成功超过1小时,不可取消`);
            }
            break;
          default:
            console.error(`[订单${context.orderId}] 支付成功状态不支持${action.type}操作`);
        }
      }
    }
    
    // 4. 支付失败状态
    class PayFailedState extends OrderState {
      getStatus(): OrderStatus {
        return "PAY_FAILED";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "RETRY_PAY": // 重试支付
            context.setState(new PendingPayState());
            break;
          case "CANCEL_ORDER": // 取消订单
            context.setState(new CanceledState());
            break;
          default:
            console.error(`[订单${context.orderId}] 支付失败状态不支持${action.type}操作`);
        }
      }
    }
    
    // 5. 待发货状态
    class PendingSendState extends OrderState {
      getStatus(): OrderStatus {
        return "PENDING_SEND";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "CONFIRM_SEND": // 确认发货
            context.setState(new ShippedState());
            break;
          case "CANCEL_SEND": // 取消发货
            context.setState(new PaySuccessState());
            break;
          default:
            console.error(`[订单${context.orderId}] 待发货状态不支持${action.type}操作`);
        }
      }
    }
    
    // 6. 已发货状态
    class ShippedState extends OrderState {
      getStatus(): OrderStatus {
        return "SHIPPED";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "CONFIRM_RECEIVE": // 确认收货
            context.setState(new ReceivedState());
            break;
          case "APPLY_REFUND": // 申请售后
            if (this.checkAllow(context, ["SHIPPED"])) {
              context.setState(new RefundApplyState());
            }
            break;
          default:
            console.error(`[订单${context.orderId}] 已发货状态不支持${action.type}操作`);
        }
      }
    }
    
    // 7. 已收货状态
    class ReceivedState extends OrderState {
      getStatus(): OrderStatus {
        return "RECEIVED";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "COMPLETE_ORDER": // 完成订单
            context.setState(new CompletedState());
            break;
          case "APPLY_REFUND": // 申请售后(7天内)
            const within7Days = action.payload?.within7Days || false;
            if (within7Days && this.checkAllow(context, ["RECEIVED"])) {
              context.setState(new RefundApplyState());
            } else {
              console.error(`[订单${context.orderId}] 已收货超过7天,不可申请售后`);
            }
            break;
          default:
            console.error(`[订单${context.orderId}] 已收货状态不支持${action.type}操作`);
        }
      }
    }
    
    // 8. 申请售后状态
    class RefundApplyState extends OrderState {
      getStatus(): OrderStatus {
        return "REFUND_APPLY";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "PASS_REFUND": // 售后通过
            context.setState(new RefundPassState());
            break;
          case "REJECT_REFUND": // 售后驳回
            context.setState(new RefundRejectState());
            break;
          case "CANCEL_REFUND": // 取消售后
            // 回溯到上一个状态(已发货/已收货)
            const history = context.getHistoryStatus();
            const prevStatus = history[history.length - 2] || "RECEIVED";
            switch (prevStatus) {
              case "SHIPPED": context.setState(new ShippedState()); break;
              case "RECEIVED": context.setState(new ReceivedState()); break;
              default: context.setState(new CompletedState());
            }
            break;
          default:
            console.error(`[订单${context.orderId}] 申请售后状态不支持${action.type}操作`);
        }
      }
    }
    
    // 9. 售后通过状态
    class RefundPassState extends OrderState {
      getStatus(): OrderStatus {
        return "REFUND_PASS";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "COMPLETE_REFUND": // 完成退款
            context.setState(new CompletedState());
            break;
          default:
            console.error(`[订单${context.orderId}] 售后通过状态不支持${action.type}操作`);
        }
      }
    }
    
    // 10. 售后驳回状态
    class RefundRejectState extends OrderState {
      getStatus(): OrderStatus {
        return "REFUND_REJECT";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "REAPPLY_REFUND": // 重新申请售后
            context.setState(new RefundApplyState());
            break;
          case "ABANDON_REFUND": // 放弃售后
            context.setState(new ReceivedState());
            break;
          default:
            console.error(`[订单${context.orderId}] 售后驳回状态不支持${action.type}操作`);
        }
      }
    }
    
    // 11. 订单完结状态(终态,不可操作)
    class CompletedState extends OrderState {
      getStatus(): OrderStatus {
        return "COMPLETED";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        console.error(`[订单${context.orderId}] 订单已完结(${this.getStatus()}),不支持任何操作`);
      }
    }
    
    // 12. 订单取消状态(可回溯)
    class CanceledState extends OrderState {
      getStatus(): OrderStatus {
        return "CANCELED";
      }
    
      handle(context: OrderContext, action: { type: string; payload?: any }): void {
        switch (action.type) {
          case "RECREATE_ORDER": // 重新下单
            context.setState(new PendingPayState());
            break;
          default:
            console.error(`[订单${context.orderId}] 订单已取消(${this.getStatus()}),仅支持重新下单`);
        }
      }
    }
    
    // ==================== 测试复杂状态流转 ====================
    const order = new OrderContext("ORD20260226001", 199);
    
    // 1. 初始→待支付→支付成功→待发货→已发货
    order.execute({ type: "CREATE_ORDER" });
    order.execute({ type: "PAY", payload: { amount: 199 } });
    order.execute({ type: "SEND_GOODS" });
    order.execute({ type: "CONFIRM_SEND" });
    
    // 2. 已发货→申请售后→售后驳回→重新申请→售后通过→完成退款→完结
    order.execute({ type: "APPLY_REFUND" });
    order.execute({ type: "REJECT_REFUND" });
    order.execute({ type: "REAPPLY_REFUND" });
    order.execute({ type: "PASS_REFUND" });
    order.execute({ type: "COMPLETE_REFUND" });
    
    // 3. 尝试操作完结订单(禁止)
    order.execute({ type: "APPLY_REFUND" });
    
    // 4. 打印历史状态
    console.log("订单历史状态:", order.getHistoryStatus());
    console.log("最终状态:", order.getCurrentStatus());
    

状态模式的优势

  1. 单一职责原则:将与特定状态相关的行为封装在独立的类中;

  2. 开闭原则:添加新状态无需修改现有状态类和上下文;

  3. 消除条件语句:消除大量的条件分支语句;

  4. 状态转换明确:状态间的转换更加清晰和可控;

注意事项

  1. 类数量增加:每个状态都需要一个类,可能导致类数量过多;

  2. 状态共享:如果状态对象没有实例变量,可以被多个上下文共享;

  3. 状态转换逻辑:可以在状态类或上下文类中定义转换逻辑;

  4. 性能考虑:状态切换频繁时,需要注意对象创建的开销;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 状态模式核心概念
  2. 2. 状态模式的常用场景
    1. 2.1. 表单状态流转
    2. 2.2. 播放器状态控制
    3. 2.3. 页面 / 组件生命周期状态
    4. 2.4. 游戏角色状态(小游戏 / 互动场景)
    5. 2.5. 订单 / 交易状态管理(最典型)
  3. 3. 状态模式的优势
  4. 4. 注意事项