前端小白变形记:你要学会这些设计模式!第八弹:状态模式

前言

  1. 从第一篇工厂模式开始,我会持续地更新每一种设计模式的内容,争取用通俗易懂的语言讲解和解释清楚。如果对你学习设计模式有帮助,请不要吝啬手中的赞~ 如果对文章内容有任何疑惑都可以在评论区提出和讨论~

  2. 本系列文章中的完整源码已上传 github 仓库,你可以在这里 github.com/FatMii/Desi...获取。

    同样的,如果对你有帮助,请给我一个star~谢谢

  3. 设计模式合集链接:

    前端小白变形记:你要学会这些设计模式!首发:工厂模式

    前端小白变形记:你要学会这些设计模式!第二弹:单例模式

    前端小白变形记:你要学会这些设计模式!第三弹:责任链模式

    前端小白变形记:你要学会这些设计模式!第四弹:观察者模式

    前端小白变形记:你要学会这些设计模式!第五弹:发布订阅模式

    前端小白变形记:你要学会这些设计模式!第六弹:策略模式

    前端小白变形记:你要学会这些设计模式!第七弹:代理模式

Hello~ 大家好,本篇文章我们继续学习设计模式第八篇:状态模式

一、介绍

状态模式是一种行为型设计模式,其核心是将对象的状态与状态对应的行为分离,让对象在不同状态下自动切换对应的行为,而不是通过大量 if-else 或 switch-case 判断状态。简单来说,就是让 "状态自己决定该做什么"------ 比如红绿灯,红灯时车辆停止、行人等待,绿灯时车辆通行、行人停止,每个状态都有明确的行为,状态切换时行为也自动切换,无需外部频繁判断。

状态模式主要包含以下三个关键部分:

  1. 环境类(Context) :这是拥有状态的对象,它持有当前状态的引用,对外提供统一的接口(如 "切换状态"),并将与状态相关的行为委托给当前状态对象处理,自身不直接包含状态逻辑。
  1. 抽象状态类(State) :这是一个通用接口,定义了所有具体状态共有的行为方法(如 "处理当前状态逻辑""切换到下一个状态"),保证所有状态在行为上具有一致性。
  1. 具体状态类(Concrete State) :这些是实现了抽象状态接口的具体状态,每个类对应一个具体状态,包含该状态下的行为逻辑,以及状态切换的规则(比如红灯状态的下一个状态是绿灯)。

通过这种设计,状态模式能让代码摆脱复杂的条件判断,将每个状态的行为封装成独立类,不仅提高了代码的可读性和可维护性,还能轻松扩展新状态(如给红绿灯新增 "黄灯" 状态)。

二、前端场景:选项卡切换

在前端开发中,选项卡(Tab)是非常常见的组件 ------ 比如商品详情页的 "商品介绍""规格参数""用户评价" 切换,点击不同选项卡时,会显示对应内容并高亮当前选项。如果用传统 if-else 实现,会把所有状态判断和 DOM 操作混在一起,代码臃肿且难维护,而状态模式能让每个选项卡状态独立管理自己的行为。

1. 传统方式:混乱的条件判断

传统实现中,会通过判断当前激活的选项卡索引或 ID,来执行对应的 DOM 操作(显示内容、添加高亮样式),代码耦合度高:

js 复制代码
// 传统选项卡:用if-else判断状态,逻辑耦合
class TabComponent {
  constructor(tabContainer) {
    // 获取DOM元素
    this.tabs = tabContainer.querySelectorAll('.tab-item');
    this.panels = tabContainer.querySelectorAll('.tab-panel');
    // 当前激活的选项卡索引
    this.activeIndex = 0;
    // 初始化:激活第一个选项卡
    this.init();
  }
  init() {
    // 给每个选项卡绑定点击事件
    this.tabs.forEach((tab, index) => {
      tab.addEventListener('click', () => this.switchTab(index));
    });
    // 初始激活第一个
    this.updateTabUI(this.activeIndex);
  }
  // 切换选项卡:核心逻辑(大量条件判断)
  switchTab(targetIndex) {
    // 避免重复点击同一选项卡
    if (targetIndex === this.activeIndex) return;
    // 1. 移除当前激活选项卡的高亮样式
    this.tabs[this.activeIndex].classList.remove('active');
    // 2. 隐藏当前激活的内容面板
    this.panels[this.activeIndex].classList.add('hidden');
    // 3. 更新当前激活索引
    this.activeIndex = targetIndex;
    // 4. 给目标选项卡添加高亮样式
    this.tabs[targetIndex].classList.add('active');
    // 5. 显示目标内容面板
    this.panels[targetIndex].classList.remove('hidden');
    // 如果后续需要给不同选项卡添加特殊逻辑(如"用户评价"加载评论数据)
    // 会新增大量if-else:
    // if (targetIndex === 2) {
    //   this.loadComments();
    // } else if (targetIndex === 1) {
    //   this.loadSpecs();
    // }
  }
  // 辅助方法:更新UI(初始调用)
  updateTabUI(activeIndex) {
    this.tabs[activeIndex].classList.add('active');
    this.panels[activeIndex].classList.remove('hidden');
  }
}
// 使用选项卡:传入容器DOM
const tabContainer = document.getElementById('product-tab');
new TabComponent(tabContainer);

这种方式的问题很明显:所有状态(选项卡索引)对应的行为(样式切换、内容显示、特殊逻辑)都写在 switchTab 方法中,新增选项卡或特殊逻辑时,必须修改该方法,违背 "开闭原则",代码会越来越臃肿。

2. 状态模式:状态与行为分离的优雅实现

用状态模式改造后,我们将每个选项卡视为一个 "状态",每个状态负责自己的行为(高亮样式、显示内容、特殊逻辑),环境类只负责管理状态切换,代码结构更清晰:

定义抽象状态类(State)

抽象状态接口定义每个选项卡状态必须实现的行为方法:

js 复制代码
// 抽象状态类:选项卡状态接口
class TabState {
  constructor(context) {
    // 持有环境类引用(用于切换状态)
    this.context = context;
  }
  // 行为1:激活当前状态(高亮选项卡、显示面板)
  activate() {
    throw new Error("激活状态方法未实现!");
  }
  // 行为2:切换到目标状态(由具体状态决定是否允许切换)
  switchTo(targetState) {
    throw new Error("切换状态方法未实现!");
  }
}

实现具体状态类(Concrete State)

每个选项卡对应一个具体状态类,实现该状态下的行为逻辑(如激活时高亮样式、显示内容,以及切换规则):

js 复制代码
// 具体状态1:商品介绍选项卡
class IntroTabState extends TabState {
  constructor(context) {
    super(context);
    // 状态标识(对应选项卡索引)
    this.index = 0;
  }
  // 激活当前状态:高亮选项卡 + 显示内容面板
  activate() {
    // 高亮当前选项卡
    this.context.tabs[this.index].classList.add('active');
    // 显示当前内容面板
    this.context.panels[this.index].classList.remove('hidden');
    console.log("激活【商品介绍】选项卡");
    // 商品介绍的特殊逻辑(如初始化图片轮播)
    this.initImageCarousel();
  }
  // 切换到目标状态:先取消当前状态激活,再让环境类切换到目标状态
  switchTo(targetState) {
    // 取消当前状态激活(移除高亮、隐藏面板)
    this.context.tabs[this.index].classList.remove('active');
    this.context.panels[this.index].classList.add('hidden');
    // 通知环境类切换到目标状态
    this.context.setCurrentState(targetState);
  }
  // 商品介绍的特殊逻辑(独立封装,不影响其他状态)
  initImageCarousel() {
    console.log("初始化商品图片轮播");
    // 实际图片轮播初始化逻辑...
  }
}

// 具体状态2:规格参数选项卡
class SpecTabState extends TabState {
  constructor(context) {
    super(context);
    this.index = 1;
  }
  activate() {
    this.context.tabs[this.index].classList.add('active');
    this.context.panels[this.index].classList.remove('hidden');
    console.log("激活【规格参数】选项卡");
    // 规格参数的特殊逻辑(如加载规格数据)
    this.loadSpecData();
  }
  switchTo(targetState) {
    this.context.tabs[this.index].classList.remove('active');
    this.context.panels[this.index].classList.add('hidden');
    this.context.setCurrentState(targetState);
  }
  // 规格参数的特殊逻辑
  loadSpecData() {
    console.log("加载商品规格参数数据");
    // 实际接口请求逻辑...
  }
}
// 具体状态3:用户评价选项卡
class CommentTabState extends TabState {
  constructor(context) {
    super(context);
    this.index = 2;
  }
  activate() {
    this.context.tabs[this.index].classList.add('active');
    this.context.panels[this.index].classList.remove('hidden');
    console.log("激活【用户评价】选项卡");
    // 用户评价的特殊逻辑(如加载评论列表)
    this.loadCommentList();
  }
  switchTo(targetState) {
    this.context.tabs[this.index].classList.remove('active');
    this.context.panels[this.index].classList.add('hidden');
    this.context.setCurrentState(targetState);
  }
  // 用户评价的特殊逻辑
  loadCommentList() {
    console.log("加载用户评价列表");
    // 实际接口请求逻辑...
  }
}

实现环境类(Context)

环境类管理所有状态,持有当前状态引用,对外提供切换状态的接口,并将行为委托给当前状态:

kotlin 复制代码
// 环境类:选项卡组件(管理状态切换)
class TabContext {
  constructor(tabContainer) {
    // 1. 获取DOM元素
    this.tabs = tabContainer.querySelectorAll('.tab-item');
    this.panels = tabContainer.querySelectorAll('.tab-panel');
    // 2. 初始化所有状态实例
    this.introState = new IntroTabState(this); // 商品介绍状态
    this.specState = new SpecTabState(this);   // 规格参数状态
    this.commentState = new CommentTabState(this); // 用户评价状态
    // 3. 初始状态:商品介绍
    this.currentState = this.introState;
    // 4. 绑定事件(对外提供交互入口)
    this.bindEvents();
    // 5. 激活初始状态
    this.currentState.activate();
  }
  // 绑定选项卡点击事件
  bindEvents() {
    // 点击"商品介绍"选项卡
    this.tabs[0].addEventListener('click', () => {
      if (this.currentState !== this.introState) {
        this.currentState.switchTo(this.introState);
      }
    });
    // 点击"规格参数"选项卡
    this.tabs[1].addEventListener('click', () => {
      if (this.currentState !== this.specState) {
        this.currentState.switchTo(this.specState);
      }
    });
    // 点击"用户评价"选项卡
    this.tabs[2].addEventListener('click', () => {
      if (this.currentState !== this.commentState) {
        this.currentState.switchTo(this.commentState);
      }
    });
  }
  // 切换当前状态(由具体状态调用)
  setCurrentState(newState) {
    this.currentState = newState;
    // 激活新状态的行为
    this.currentState.activate();
  }
}

使用状态模式

客户端只需传入选项卡容器 DOM,环境类会自动管理状态,使用方式简洁:

html 复制代码
<!-- 选项卡HTML结构 -->
<div id="product-tab" class="tab-container">
  <!-- 选项卡头部 -->
  <div class="tab-header">
    <div class="tab-item">商品介绍</div>
    <div class="tab-item">规格参数</div>
    <div class="tab-item">用户评价</div>
  </div>
  <!-- 选项卡内容面板 -->
  <div class="tab-content">
    <div class="tab-panel hidden">商品介绍内容:高清图片、商品特点...</div>
    <div class="tab-panel hidden">规格参数内容:尺寸、材质、重量...</div>
    <div class="tab-panel hidden">用户评价内容:好评率98%、用户留言...</div>
  </div>
</div>
<script>
// 初始化选项卡(传入容器DOM)
const tabContainer = document.getElementById('product-tab');
new TabContext(tabContainer);
// 点击"规格参数"选项卡时的输出:
// 1. 取消当前状态(商品介绍):移除高亮、隐藏面板
// 2. 切换到规格参数状态
// 3. 激活规格参数状态:添加高亮、显示面板 → 输出"激活【规格参数】选项卡"
// 4. 执行特殊逻辑 → 输出"加载商品规格参数数据"
</script>

改造后的优势非常明显:如果需要新增 "售后服务" 选项卡,只需新增一个 ServiceTabState 类,在环境类中初始化并绑定事件,无需修改任何现有状态的代码;如果需要修改 "用户评价" 的加载逻辑,只需修改 CommentTabState 的 loadCommentList 方法,完全不影响其他状态,扩展性和可维护性大幅提升。

三、后端场景:订单状态流转

在后端开发中,订单状态流转是典型场景 ------ 订单有 "待支付" "已支付" "待发货" "已发货" "已完成" 等状态,每个状态下能执行的操作不同(如 "待支付" 状态可执行 "支付" 操作,"已支付" 状态可执行 "取消订单" 或 "申请发货" 操作)。用传统 if-else 实现会导致代码混乱,而状态模式能让每个状态管理自己的合法操作和状态切换规则。

1. 传统方式:冗余的状态判断

传统实现中,会通过 switch-case 判断订单当前状态,再决定是否允许执行操作(如支付、发货),代码冗余且易出错:

java 复制代码
// 传统订单状态管理:用switch-case判断状态,逻辑耦合
public class OrderService {
    // 订单状态枚举
    public enum OrderStatus {
        PENDING_PAYMENT, // 待支付
        PAID,            // 已支付
        PENDING_SHIPMENT,// 待发货
        SHIPPED,         // 已发货
        COMPLETED        // 已完成
    }
    // 执行订单操作(支付、发货、确认收货等)
    public String executeOperation(Order order, String operation) {
        OrderStatus currentStatus = order.getStatus();
        // 根据当前状态判断是否允许执行操作
        switch (currentStatus) {
            case PENDING_PAYMENT:
                // 待支付状态:仅允许"支付"操作
                if ("pay".equals(operation)) {
                    // 执行支付逻辑
                    order.setStatus(OrderStatus.PAID);
                    return "支付成功,订单状态更新为【已支付】";
                } else if ("cancel".equals(operation)) {
                    // 待支付状态也允许"取消订单"
                    order.setStatus(OrderStatus.COMPLETED); // 取消后订单完成(简化)
                    return "订单取消成功,订单状态更新为【已完成】";
                } else {
                    return "待支付状态不支持【" + operation + "】操作";
                }
            case PAID:
                // 已支付状态:允许"申请发货""取消订单"
                if ("ship".equals(operation)) {
                    order.setStatus(OrderStatus.PENDING_SHIPMENT);
                    return "申请发货成功,订单状态更新为【待发货】";
                } else if ("cancel".equals(operation)) {
                    order.setStatus(OrderStatus.COMPLETED);
                    return "订单取消成功,订单状态更新为【已完成】";
                } else {
                    return "已支付状态不支持【" + operation + "】操作";
                }
            case PENDING_SHIPMENT:
                // 待发货状态:仅允许"发货"
                if ("ship".equals(operation)) {
                    order.setStatus(OrderStatus.SHIPPED);
                    return "发货成功,订单状态更新为【已发货】";
                } else {
                    return "待发货状态不支持【" + operation + "】操作";
                }
            case SHIPPED:
                // 已发货状态:仅允许"确认收货"
                if ("confirm".equals(operation)) {
                    order.setStatus(OrderStatus.COMPLETED);
                    return "确认收货成功,订单状态更新为【已完成】";
                } else {
                    return "已发货状态不支持【" + operation + "】操作";
                }
            case COMPLETED:
                // 已完成状态:不允许任何操作
                return "已完成状态不支持任何操作";
            default:
                return "未知订单状态";
        }
    }
}
// 订单实体类
class Order {
    private String orderId;
    private OrderService.OrderStatus status;
    // 构造器、getter、setter
    public Order(String orderId, OrderService.OrderStatus status) {
        this.orderId = orderId;
        this.status = status;
    }
    public OrderService.OrderStatus getStatus() {
        return status;
    }
    public void setStatus(OrderService.OrderStatus status) {
        this.status = status;
    }
}
// 使用传统订单服务
public class Main {
    public static void main(String[] args) {
        OrderService orderService = new OrderService();
        // 创建待支付订单
        Order order = new Order("ORDER001", OrderService.OrderStatus.PENDING_PAYMENT);
        // 执行支付操作
        System.out.println(orderService.executeOperation(order, "pay")); 
        // 输出:支付成功,订单状态更新为【已支付】
        // 执行发货操作
        System.out.println(orderService.executeOperation(order, "ship")); 
        // 输出:申请发货成功,订单状态更新为【待发货】
        // 尝试在待发货状态执行"确认收货"(不允许)
        System.out.println(orderService.executeOperation(order, "confirm")); 
        // 输出:待发货状态不支持【confirm】操作
    }
}

这种方式的问题很突出:所有状态的操作规则都写在 executeOperation 方法中,新增状态(如 "退款中")或修改操作规则(如 "已支付" 状态不允许取消)时,必须修改该方法,代码会越来越复杂,且容易遗漏状态判断。

2. 状态模式改造

用状态模式改造后,我们将每个订单状态封装成独立类,每个状态管理自己的合法操作和状态切换规则,环境类(订单)只负责持有当前状态并委托行为:

定义抽象状态类(State)

抽象状态接口定义每个订单状态必须实现的行为方法(执行操作、获取状态标识):

java 复制代码
// 抽象状态类:订单状态接口
public interface OrderState {
    // 获取状态标识(如"待支付""已支付")
    String getStateName();
    // 执行操作(支付、发货、确认收货等),返回操作结果
    String executeOperation(OrderContext order, String operation);
}

实现具体状态类(Concrete State)

每个订单状态对应一个具体状态类,实现该状态下的合法操作和状态切换逻辑:

java 复制代码
// 具体状态1:待支付状态
public class PendingPaymentState implements OrderState {
    @Override
    public String getStateName() {
        return "待支付";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 待支付状态仅支持"支付"和"取消订单"操作
        switch (operation) {
            case "pay":
                // 执行支付逻辑(如扣减余额、生成支付记录)
                System.out.println("执行支付逻辑:订单" + order.getOrderId());
                // 切换到"已支付"状态
                order.setState(new PaidState());
                return "支付成功,订单状态更新为【" + order.getState().getStateName() + "】";
            case "cancel":
                // 执行取消订单逻辑(如释放库存)
                System.out.println("执行取消订单逻辑:订单" + order.getOrderId());
                // 切换到"已完成"状态(简化)
                order.setState(new CompletedState());
                return "订单取消成功,订单状态更新为【" + order.getState().getStateName() + "】";
            default:
                return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}
// 具体状态2:已支付状态
public class PaidState implements OrderState {
    @Override
    public String getStateName() {
        return "已支付";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 已支付状态支持"申请发货"和"取消订单"
        switch (operation) {
            case "ship":
                // 执行申请发货逻辑(如通知仓库)
                System.out.println("执行申请发货逻辑:订单" + order.getOrderId());
                // 切换到"待发货"状态
                order.setState(new PendingShipmentState());
                return "申请发货成功,订单状态更新为【" + order.getState().getStateName() + "】";
            case "cancel":
                // 执行取消订单逻辑(如退款、释放库存)
                System.out.println("执行取消订单逻辑(含退款):订单" + order.getOrderId());
                // 切换到"已完成"状态
                order.setState(new CompletedState());
                return "订单取消成功(已退款),订单状态更新为【" + order.getState().getStateName() + "】";
            default:
                return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}
// 具体状态3:待发货状态
public class PendingShipmentState implements OrderState {
    @Override
    public String getStateName() {
        return "待发货";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 待发货状态仅支持"发货"操作
        if ("ship".equals(operation)) {
            // 执行发货逻辑(如生成物流单)
            System.out.println("执行发货逻辑:订单" + order.getOrderId());
            // 切换到"已发货"状态
            order.setState(new ShippedState());
            return "发货成功,订单状态更新为【" + order.getState().getStateName() + "】";
        } else {
            return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}
// 具体状态4:已发货状态
public class ShippedState implements OrderState {
    @Override
    public String getStateName() {
        return "已发货";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 已发货状态仅支持"确认收货"操作
        if ("confirm".equals(operation)) {
            // 执行确认收货逻辑(如结算商家款项)
            System.out.println("执行确认收货逻辑:订单" + order.getOrderId());
            // 切换到"已完成"状态
            order.setState(new CompletedState());
            return "确认收货成功,订单状态更新为【" + order.getState().getStateName() + "】";
        } else {
            return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}
// 具体状态5:已完成状态
public class CompletedState implements OrderState {
    @Override
    public String getStateName() {
        return "已完成";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 已完成状态不支持任何操作
        return "【" + getStateName() + "】状态不支持任何操作";
    }
}

实现环境类(Context)

环境类(订单)持有当前状态引用,对外提供执行操作和切换状态的接口,自身不包含状态逻辑:

java 复制代码
// 环境类:订单(管理状态和委托行为)
public class OrderContext {
    private String orderId;
    private OrderState state; // 当前状态
    // 构造器:初始化订单ID和初始状态(默认待支付)
    public OrderContext(String orderId) {
        this.orderId = orderId;
        this.state = new PendingPaymentState(); // 初始状态为待支付
    }
    // 执行订单操作(对外统一接口)
    public String executeOperation(String operation) {
        // 将操作委托给当前状态处理
        return state.executeOperation(this, operation);
    }
    // 切换状态(由具体状态类调用)
    public void setState(OrderState newState) {
        this.state = newState;
    }
    // 获取当前状态名称(对外展示用)
    public String getCurrentStateName() {
        return state.getStateName();
    }
    // getter:供具体状态类获取订单ID
    public String getOrderId() {
        return orderId;
    }
}

使用状态模式

客户端只需创建订单环境类,调用 executeOperation 方法即可,无需关心状态判断和切换逻辑:

java 复制代码
// 使用状态模式的订单服务
public class StatePatternMain {
    public static void main(String[] args) {
        // 1. 创建订单(初始状态为"待支付")
        OrderContext order = new OrderContext("ORDER001");
        System.out.println("初始订单状态:" + order.getCurrentStateName()); 
        // 输出:初始订单状态:待支付
        // 2. 执行"支付"操作
        System.out.println(order.executeOperation("pay")); 
        // 输出:执行支付逻辑:订单ORDER001 → 支付成功,订单状态更新为【已支付】
        // 3. 执行"申请发货"操作
        System.out.println(order.executeOperation("ship")); 
        // 输出:执行申请发货逻辑:订单ORDER001 → 申请发货成功,订单状态更新为【待发货】
        // 4. 执行"发货"操作
        System.out.println(order.executeOperation("ship")); 
        // 输出:执行发货逻辑:订单ORDER001 → 发货成功,订单状态更新为【已发货】
        // 5. 执行"确认收货"操作
        System.out.println(order.executeOperation("confirm")); 
        // 输出:执行确认收货逻辑:订单ORDER001 → 确认收货成功,订单状态更新为【已完成】
        // 6. 尝试在已完成状态执行"取消"操作(不允许)
        System.out.println(order.executeOperation("cancel")); 
        // 输出:【已完成】状态不支持任何操作
    }
}

实际业务扩展:新增 "退款中" 状态

如果业务需要新增 "退款中" 状态(如用户在 "已发货" 状态申请退款),只需新增一个具体状态类,无需修改任何现有代码:

java 复制代码
// 新增具体状态:退款中状态
public class RefundingState implements OrderState {
    @Override
    public String getStateName() {
        return "退款中";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        // 退款中状态仅支持"退款完成"操作
        if ("refund_complete".equals(operation)) {
            System.out.println("执行退款完成逻辑:订单" + order.getOrderId());
            order.setState(new CompletedState());
            return "退款完成,订单状态更新为【" + order.getState().getStateName() + "】";
        } else {
            return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}
// 同时修改"已发货"状态,允许执行"申请退款"操作
public class ShippedState implements OrderState {
    @Override
    public String getStateName() {
        return "已发货";
    }
    @Override
    public String executeOperation(OrderContext order, String operation) {
        if ("confirm".equals(operation)) {
            // 原确认收货逻辑...
        } else if ("apply_refund".equals(operation)) { // 新增"申请退款"操作
            System.out.println("执行申请退款逻辑:订单" + order.getOrderId());
            order.setState(new RefundingState()); // 切换到退款中状态
            return "申请退款成功,订单状态更新为【" + order.getState().getStateName() + "】";
        } else {
            return "【" + getStateName() + "】状态不支持【" + operation + "】操作";
        }
    }
}

这种扩展方式完全符合 "开闭原则",新增状态时无需修改现有代码,极大降低了维护成本。

总结:状态模式的核心价值

状态模式的核心价值在于 "状态自治":让每个状态自己管理对应的行为和切换规则,替代复杂的条件判断,实现 "状态决定行为" 的逻辑。它解决了传统 if-else 代码臃肿、难维护的问题,同时让状态扩展更灵活,符合 "开闭原则"。

下次当你面对满屏的 if-else 状态判断时,不妨试试状态模式,让每个状态 "自己做主",让代码变得更优雅、更易维护!

相关推荐
chxii16 分钟前
6.3Element UI 的表单
javascript·vue.js·elementui
张努力17 分钟前
从零开始的开发一个vite插件:一个程序员的"意外"之旅 🚀
前端·vue.js
远帆L17 分钟前
前端批量导入内容——word模板方案实现
前端
Codebee22 分钟前
OneCode3.0-RAD 可视化设计器 配置手册
前端·低代码
深兰科技23 分钟前
深兰科技:搬迁公告,我们搬家了
javascript·人工智能·python·科技·typescript·laravel·深兰科技
葡萄城技术团队37 分钟前
【SpreadJS V18.2 新版本】设计器新特性:四大主题方案,助力 UI 个性化与品牌适配
前端
lumi.1 小时前
Swiper属性全解析:快速掌握滑块视图核心配置!(2.3补充细节,详细文档在uniapp官网)
前端·javascript·css·小程序·uni-app
调皮LE1 小时前
可放大缩小弹窗组件,基于element-ui的vue2版本
前端
陈随易1 小时前
10年老前端,分享20+严选技术栈
前端·后端·程序员
我的小月月1 小时前
基于Canvas实现的网页取色器功能解析
前端