织梦系统网站地图模板下载,东莞网站优化指导,wordpress怎样修改原生登录按钮,网站运营阶段策略模式#xff08;Strategy Pattern#xff09;详解
策略模式#xff08;Strategy Pattern#xff09;是一种行为型设计模式#xff0c;用于定义一系列算法#xff0c;并将每种算法封装到独立的策略类中#xff0c;使它们可以相互替换#xff0c;从而使算法的变化独…策略模式Strategy Pattern详解
策略模式Strategy Pattern是一种行为型设计模式用于定义一系列算法并将每种算法封装到独立的策略类中使它们可以相互替换从而使算法的变化独立于使用算法的客户端即使用这些算法的代码。通过策略模式用户可以根据需要选择不同的算法实现系统的 开放-关闭原则Open/Closed Principle。
1. 策略模式的定义
1.1 什么是策略模式
策略模式定义了一系列算法将每个算法封装起来并且使它们可以互相替换。策略模式让算法独立于使用它的客户端而变化。它的核心思想是定义一组可互换的策略对象将这些策略对象注入到上下文对象中从而让上下文对象在运行时可以动态地更换不同的策略。
1.2 策略模式的特点
封装变化将算法封装在独立的类中使得算法的修改不会影响使用算法的客户端。消除条件语句避免在客户端代码中使用大量的 if-else 或 switch-case 语句。提高扩展性新增策略时只需添加新的策略类而无需修改现有代码。
2. 策略模式的结构
策略模式通常包含以下几个角色
策略接口Strategy 定义所有支持的算法的公共接口。具体策略ConcreteStrategy 实现策略接口的具体算法。上下文Context 持有策略接口的引用用于调用具体的策略方法。
类图
-----------------
| Strategy |---------------------
|-----------------| |
| algorithm() | |
----------------- |^ || |
----------------- -------------------
| ConcreteStrategyA | | ConcreteStrategyB |
|-------------------| |--------------------|
| algorithm() | | algorithm() |
------------------- --------------------^|
---------------------
| Context |
|---------------------|
| - strategy: Strategy|
| setStrategy() |
| executeAlgorithm()|
---------------------3. 策略模式的实现
为了更好地理解策略模式我们使用一个简单的示例来演示其工作原理。假设我们要开发一个应用程序用于计算商品的促销折扣。不同的促销活动有不同的折扣计算策略。
3.1 Java 示例代码
// 策略接口
interface DiscountStrategy {double calculateDiscount(double price);
}// 具体策略类圣诞节促销
class ChristmasDiscount implements DiscountStrategy {Overridepublic double calculateDiscount(double price) {System.out.println(使用圣诞节促销折扣);return price * 0.9; // 10% 折扣}
}// 具体策略类新年促销
class NewYearDiscount implements DiscountStrategy {Overridepublic double calculateDiscount(double price) {System.out.println(使用新年促销折扣);return price * 0.8; // 20% 折扣}
}// 具体策略类无折扣
class NoDiscount implements DiscountStrategy {Overridepublic double calculateDiscount(double price) {System.out.println(没有折扣);return price;}
}// 上下文类
class ShoppingCart {private DiscountStrategy discountStrategy;// 设置策略public void setDiscountStrategy(DiscountStrategy discountStrategy) {this.discountStrategy discountStrategy;}// 计算最终价格public double calculateFinalPrice(double price) {return discountStrategy.calculateDiscount(price);}
}// 测试客户端
public class StrategyPatternDemo {public static void main(String[] args) {ShoppingCart cart new ShoppingCart();// 使用圣诞节折扣cart.setDiscountStrategy(new ChristmasDiscount());System.out.println(最终价格: cart.calculateFinalPrice(100.0));// 使用新年折扣cart.setDiscountStrategy(new NewYearDiscount());System.out.println(最终价格: cart.calculateFinalPrice(100.0));// 使用无折扣cart.setDiscountStrategy(new NoDiscount());System.out.println(最终价格: cart.calculateFinalPrice(100.0));}
}输出结果
使用圣诞节促销折扣
最终价格: 90.0
使用新年促销折扣
最终价格: 80.0
没有折扣
最终价格: 100.04. 策略模式的应用场景
策略模式适合以下场景
多个类只在行为上有所不同 当多个类的功能类似仅在算法或行为上有所区别时可以使用策略模式来封装这些行为。消除条件语句 当系统中有大量的 if-else 或 switch-case 语句时可以考虑使用策略模式来替代这些条件语句。需要动态更改算法 例如支付方式信用卡、PayPal、比特币、排序算法快速排序、归并排序、日志记录方式文件、数据库、控制台。系统需要灵活扩展 可以在不修改原有代码的情况下轻松添加新的策略。
5. 策略模式的优缺点
5.1 优点
符合开闭原则可以在不修改原有代码的情况下扩展新的策略。避免使用复杂的条件判断通过策略的多态性来消除条件语句使代码更清晰、更易维护。提高代码的复用性将每个策略封装到独立的类中使其可以被多个上下文重用。
5.2 缺点
增加类的数量每个策略都需要定义一个类导致类的数量增加可能会使系统变得复杂。客户端必须知道所有的策略客户端需要了解所有可用的策略以便在运行时选择合适的策略。策略之间无法共享数据策略类是相互独立的无法直接共享数据可能导致重复代码。
6. 策略模式的扩展
6.1 结合工厂模式Factory Pattern
策略模式可以与工厂模式结合使用通过工厂类动态创建策略对象减少客户端对策略类的直接依赖。
6.2 结合依赖注入Dependency Injection
在实际开发中策略模式常与依赖注入结合使用将策略对象通过构造函数或方法参数注入到上下文中。
6.3 Java 8 Lambda 表达式的简化
在 Java 8 中可以使用 Lambda 表达式来简化策略模式的实现
import java.util.function.Function;public class StrategyPatternWithLambda {public static void main(String[] args) {FunctionDouble, Double christmasDiscount price - price * 0.9;FunctionDouble, Double newYearDiscount price - price * 0.8;FunctionDouble, Double noDiscount price - price;double price 100.0;System.out.println(圣诞节折扣: christmasDiscount.apply(price));System.out.println(新年折扣: newYearDiscount.apply(price));System.out.println(无折扣: noDiscount.apply(price));}
}7. 策略模式的实际应用示例
支付系统 支持多种支付方式如支付宝、微信、信用卡、PayPal用户可以根据需要选择不同的支付方式。日志记录系统 可以将日志记录到文件、数据库或控制台等不同的地方日志策略可以根据配置动态切换。数据压缩算法 支持不同的数据压缩算法如 ZIP、RAR、GZIP用户可以选择不同的压缩策略。
8. 总结
策略模式是一个非常有用的设计模式尤其是在需要根据不同的条件选择不同的算法时。通过将算法封装成独立的类并将这些类抽象化为策略接口可以有效地提高代码的复用性、可维护性和扩展性。
优点符合开闭原则、消除条件语句、提高代码复用性。缺点增加类数量、客户端需要了解策略、策略间无法共享数据。适用场景算法选择、支付方式、日志记录、多样化业务逻辑。