首页 电商直播

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计

分类:电商直播
字数: (5755)
阅读: (1722)
内容摘要:架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计,

在日常开发中,我们经常会遇到需要根据不同条件执行不同逻辑的场景。如果只是简单的几个 if-else 还好,但如果条件变得复杂,代码就会变得难以维护,充斥着大量的硬编码。今天,我们就来聊聊如何使用设计模式之策略模式,来优雅地解决这类问题,让你的代码更加灵活和可扩展。

问题场景:电商平台的优惠活动

假设我们正在开发一个电商平台,需要支持多种优惠活动,比如:

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计
  • 新人优惠:首单享受 9 折
  • 会员优惠:不同等级的会员享受不同的折扣,例如:普通会员 95 折,高级会员 9 折
  • 节日优惠:特定节日享受满减活动
  • 商品优惠:部分商品参与限时折扣

如果直接使用 if-elseswitch-case 来处理这些优惠逻辑,代码将会变得非常臃肿,而且每增加一种新的优惠活动,都需要修改原来的代码,违反了开闭原则。

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计

策略模式的底层原理

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计
  • Context(环境类): 持有一个 Strategy 的引用,负责调用 Strategy 中定义的算法。
  • Strategy(抽象策略类): 定义了一个算法接口,所有的具体策略类都要实现这个接口。
  • ConcreteStrategy(具体策略类): 实现了 Strategy 接口,封装了具体的算法。

通过策略模式,我们可以将不同的优惠算法封装成不同的策略类,然后在运行时根据不同的条件选择不同的策略。

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计

代码实现:Java 示例

// 抽象策略接口
interface DiscountStrategy {
    double applyDiscount(double price);
}

// 新人优惠策略
class NewUserDiscount implements DiscountStrategy {
    @Override
    public double applyDiscount(double price) {
        return price * 0.9; // 首单 9 折
    }
}

// 会员优惠策略
class MemberDiscount implements DiscountStrategy {
    private double discountRate;

    public MemberDiscount(double discountRate) {
        this.discountRate = discountRate;
    }

    @Override
    public double applyDiscount(double price) {
        return price * discountRate;
    }
}

// 环境类
class ShoppingCart {
    private DiscountStrategy discountStrategy;

    public ShoppingCart(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public double calculatePrice(double originalPrice) {
        return discountStrategy.applyDiscount(originalPrice);
    }

    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
}

// 使用示例
public class StrategyPatternExample {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart(new NewUserDiscount());
        double price = cart.calculatePrice(100); // 新人优惠,价格为 90
        System.out.println("Price after discount: " + price);

        cart.setDiscountStrategy(new MemberDiscount(0.95)); // 设置为会员优惠
        price = cart.calculatePrice(100); // 会员优惠,价格为 95
        System.out.println("Price after member discount: " + price);
    }
}

Nginx 反向代理中的策略模式应用

虽然以上示例是 Java 代码,但策略模式的思想可以应用到很多场景。比如,在 Nginx 的配置中,我们可以通过 ngx_http_rewrite_module 模块,根据不同的请求参数或 URL,将请求转发到不同的后端服务器。这本质上也是一种策略模式的应用,不同的后端服务器就是不同的策略。

例如,我们可以根据请求的 User-Agent 字段,将来自不同设备的请求转发到不同的后端服务器,从而实现针对不同设备的优化。

http {
    map $http_user_agent $backend {
        default backend_mobile; # 默认移动端
        ~*PC backend_pc; # 匹配包含PC的User-Agent, 使用PC端
    }

    upstream backend_pc {
        server 192.168.1.101:8080; # PC端服务器
    }

    upstream backend_mobile {
        server 192.168.1.102:8080; # 移动端服务器
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://$backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

在这个例子中,map 指令定义了不同的策略(后端服务器),而 Nginx 根据 User-Agent 选择了不同的策略。

实战避坑经验

  1. 避免过度设计: 策略模式虽然强大,但并非所有场景都适用。如果只是简单的 if-else 结构,没有必要为了使用设计模式而强行使用。否则会增加代码的复杂性。
  2. 注意策略类的粒度: 策略类的粒度应该适中。如果策略类过于简单,可能会导致策略类的数量过多,难以管理。如果策略类过于复杂,可能会导致策略类的复用性降低。
  3. 考虑使用工厂模式: 如果策略类的创建过程比较复杂,可以考虑使用工厂模式来创建策略类,从而将策略类的创建逻辑与使用逻辑分离。
  4. Context 类不宜过于复杂: Context 类的主要职责是选择合适的策略并调用其方法,不应该包含过多的业务逻辑。

总结

设计模式之策略模式是一种非常有用的设计模式,可以帮助我们优雅地解决多重条件判断的问题,提高代码的灵活性和可扩展性。但是,在使用策略模式时,需要根据实际情况进行权衡,避免过度设计,并注意策略类的粒度和 Context 类的复杂度。

架构师带你深入浅出策略模式:告别硬编码,拥抱灵活设计

转载请注明出处: 键盘上的咸鱼

本文的链接地址: http://m.acea1.store/blog/932929.SHTML

本文最后 发布于2026-04-17 12:42:47,已经过了10天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 吃瓜群众 2 天前
    策略模式确实好用,但是也容易过度设计,有时候简单的 if-else 反而更清晰。
  • 土豆泥选手 1 天前
    咸鱼大佬讲的真透彻,电商平台的优惠活动这个例子太贴切了,深有体会!
  • 单身狗 4 天前
    策略模式确实好用,但是也容易过度设计,有时候简单的 if-else 反而更清晰。
  • 咕咕咕 5 天前
    策略模式确实好用,但是也容易过度设计,有时候简单的 if-else 反而更清晰。
  • 土豆泥选手 5 天前
    咸鱼大佬讲的真透彻,电商平台的优惠活动这个例子太贴切了,深有体会!