设计模式之策略模式

概述

策略模式属于行为型设计模式,主要关注对象之间的交互和职责分配,用于解决对象之间的通信、协作和行为控制等问题。

普通策略模式

在普通的策略模式中,通常包含抽象策略接口、具体策略类和环境类这三个核心部分。以之前计算会员折扣价格的场景为例,普通策略模式的实现可能是这样的:

java 复制代码
// 抽象策略接口
interface DiscountStrategy {
    double calculateDiscount(double price);
}
// 具体策略类:普通会员折扣策略
class NormalMemberDiscount implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price;
    }
}
// 具体策略类:高级会员折扣策略
class PremiumMemberDiscount implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.9;
    }
}
// 环境类
class ShoppingCart {
    private DiscountStrategy discountStrategy;
    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
    public double calculateFinalPrice(double price) {
        if (discountStrategy == null) {
            return price;
        }
        return discountStrategy.calculateDiscount(price);
    }
}
// 客户端代码
public class NormalStrategyExample {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        double originalPrice = 100.0;
        // 普通会员
        cart.setDiscountStrategy(new NormalMemberDiscount());
        double normalPrice = cart.calculateFinalPrice(originalPrice);
        System.out.println("普通会员最终价格: " + normalPrice);
        // 高级会员
        cart.setDiscountStrategy(new PremiumMemberDiscount());
        double premiumPrice = cart.calculateFinalPrice(originalPrice);
        System.out.println("高级会员最终价格: " + premiumPrice);
    }
}

在策略模式里,客户端需要直接创建具体策略类的实例,然后将其传递给环境类来使用。这就要求客户端必须了解所有具体策略类的细节,包括类名和构造方式等。

增加工厂类后的策略模式

当增加了工厂类(DiscountStrategyFactory)后,代码结构发生了变化:

java 复制代码
// 抽象策略接口
interface DiscountStrategy {
    double calculateDiscount(double price);
}
// 具体策略类:普通会员折扣策略
class NormalMemberDiscount implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price;
    }
}
// 具体策略类:高级会员折扣策略
class PremiumMemberDiscount implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.9;
    }
}
// 策略工厂类
class DiscountStrategyFactory {
    private static final java.util.Map<String, DiscountStrategy> strategyMap = new java.util.HashMap<>();
    static {
        strategyMap.put("Normal", new NormalMemberDiscount());
        strategyMap.put("Premium", new PremiumMemberDiscount());
    }
    public static DiscountStrategy getStrategy(String memberLevel) {
        return strategyMap.getOrDefault(memberLevel, new NormalMemberDiscount());
    }
}
// 环境类
class ShoppingCart {
    public double calculateFinalPrice(double price, DiscountStrategy strategy) {
        if (strategy == null) {
            return price;
        }
        return strategy.calculateDiscount(price);
    }
}
// 客户端代码
public class StrategyWithFactoryExample {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        double originalPrice = 100.0;
        // 普通会员
        DiscountStrategy normalStrategy = DiscountStrategyFactory.getStrategy("Normal");
        double normalPrice = cart.calculateFinalPrice(originalPrice, normalStrategy);
        System.out.println("普通会员最终价格: " + normalPrice);
        // 高级会员
        DiscountStrategy premiumStrategy = DiscountStrategyFactory.getStrategy("Premium");
        double premiumPrice = cart.calculateFinalPrice(originalPrice, premiumStrategy);
        System.out.println("高级会员最终价格: " + premiumPrice);
    }
}

封装策略创建逻辑:工厂类(DiscountStrategyFactory)将具体策略类的创建和管理逻辑封装起来。客户端不再需要直接创建具体策略类的实例,而是通过工厂类提供的静态方法 getStrategy 来获取所需的策略。这样客户端只需要知道代表策略的键(如 "Normal"、"Premium"),而不需要了解具体策略类的实现细节。

提高可维护性和可扩展性:当需要新增一种会员折扣策略时,只需要在工厂类的 strategyMap 中添加新的键值对,同时创建对应的具体策略类即可,不需要修改客户端代码和环境类代码。这符合开闭原则,对扩展开放,对修改关闭。

集中管理策略:使用 Map 来存储策略,方便对所有策略进行集中管理和查找。可以通过简单的键值对操作快速定位到所需的策略,提高了代码的可读性和可维护性。

综上所述,增加工厂类是在普通策略模式基础上的一种优化,它让策略模式的实现更加灵活、可维护和可扩展。

相关推荐
AI人工智能+电脑小能手15 小时前
大白话说Java设计模式-26-策略模式(业务实战篇)
java·spring·设计模式·策略模式·支付系统·算法切换
星火102420 小时前
【Groovy翻译-进阶篇】Groovy 中的设计模式
后端·设计模式·groovy
AI人工智能+电脑小能手20 小时前
大白话说Java设计模式-27-策略模式(源码剖析篇)
java·spring·设计模式·策略模式·源码分析·事务管理·comparator
SL_staff21 小时前
风控规则如何从硬编码解耦?我们在 JVS-Rules 中的实践与思考
java·spring boot·设计模式
小此方1 天前
Linux加餐(一):藏在Linux中的设计模式(一)策略模式与日志
linux·设计模式·策略模式
To_OC1 天前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
东方小月1 天前
从零开发一个 Coding Agent(十二):实现版本化 JSONL 与真实 CLI 入口
前端·设计模式·前端框架
程序员贺加贝1 天前
轻制造SaaS的生产闭环建模-BOM工单领料报工质检与入库
java·设计模式·架构
嘟嘟07172 天前
SDD 规范驱动开发:从 vibe coding 崩盘到"两次创造"
设计模式·代码规范·vibecoding
无凭2 天前
拆解 DeerFlow Memory:Agent 的长期记忆到底怎么做?
人工智能·设计模式