概述
策略模式属于行为型设计模式,主要关注对象之间的交互和职责分配,用于解决对象之间的通信、协作和行为控制等问题。
普通策略模式
在普通的策略模式中,通常包含抽象策略接口、具体策略类和环境类这三个核心部分。以之前计算会员折扣价格的场景为例,普通策略模式的实现可能是这样的:
// 抽象策略接口
interface DiscountStrategy {double calculateDiscount(double price);
}
// 具体策略类:普通会员折扣策略
class NormalMemberDiscount implements DiscountStrategy {@Overridepublic double calculateDiscount(double price) {return price;}
}
// 具体策略类:高级会员折扣策略
class PremiumMemberDiscount implements DiscountStrategy {@Overridepublic 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 {@Overridepublic double calculateDiscount(double price) {return price;}
}
// 具体策略类:高级会员折扣策略
class PremiumMemberDiscount implements DiscountStrategy {@Overridepublic 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 来存储策略,方便对所有策略进行集中管理和查找。可以通过简单的键值对操作快速定位到所需的策略,提高了代码的可读性和可维护性。
综上所述,增加工厂类是在普通策略模式基础上的一种优化,它让策略模式的实现更加灵活、可维护和可扩展。