设计模式之策略模式

发布于:2025-02-11 ⋅ 阅读:(10) ⋅ 点赞:(0)

概述

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

普通策略模式

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

// 抽象策略接口
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)后,代码结构发生了变化:

// 抽象策略接口
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 来存储策略,方便对所有策略进行集中管理和查找。可以通过简单的键值对操作快速定位到所需的策略,提高了代码的可读性和可维护性。
综上所述,增加工厂类是在普通策略模式基础上的一种优化,它让策略模式的实现更加灵活、可维护和可扩展。


网站公告

今日签到

点亮在社区的每一天
去签到