设计模式之策略模式

概述

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

普通策略模式

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

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 来存储策略,方便对所有策略进行集中管理和查找。可以通过简单的键值对操作快速定位到所需的策略,提高了代码的可读性和可维护性。

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

相关推荐
XX風40 分钟前
VTK 策略模式详解:InteractorStyle、Mapper、Picker 与可替换算法
图形渲染·策略模式
XX風1 小时前
设计模式的本质
设计模式
折哥的程序人生 · 物流技术专研11 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列
咖啡八杯13 小时前
GoF设计模式——模板方法模式
java·后端·spring·设计模式
饼干哥哥1 天前
Openclaw已死?任何Agent都能用Cli实现AI自主运营跨境电商
设计模式·openai·ai编程
折哥的程序人生 · 物流技术专研1 天前
第4篇:抽象工厂模式——产品族一键创建
java·设计模式·抽象工厂模式·创建型模式·编程进阶·产品族·扩充系列
geovindu2 天前
go: Cascading Failures Pattern
开发语言·后端·设计模式·golang·反模式·级联失效反模式
端庄的战斗机2 天前
javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
开发语言·javascript·设计模式
大侠锅锅2 天前
第 4 篇:策略模式实践——用统一接口管理 Docker 容器、原生进程与 K3s Pod
docker·容器·边缘计算·策略模式·iot