文章目录
前言
策略模式定义一系列算法,封装每个算法,并使它们可以互换。
一、介绍
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换,算法的变化不会影响到使用算法的客户。
二、特点
-
算法封装:策略模式将算法封装在独立的策略类中,使得算法可以在运行时更换。
-
接口统一:所有策略类实现同一个接口或继承自同一个抽象类,确保它们具备一致的方法签名。
-
动态替换:可以在运行时根据不同的条件或配置动态选择使用不同的策略。
-
简化客户端代码:客户端通过接口与策略对象交互,不需要了解具体的算法实现细节。
-
单一职责原则:每个策略类只关注一种算法的实现,符合单一职责原则。
三、详细介绍
1.核心组成
-
Strategy(策略接口):定义所有支持的算法的公共接口。
-
ConcreteStrategy(具体策略类):实现Strategy接口,提供具体的算法实现。
-
Context(上下文环境):使用策略接口与具体的策略类交互,持有一个策略对象的引用。
2.代码示例
策略接口
java
/**
* 购物策略类
*/
public interface ShoppingStrategy {
/**
* 结算
* @param commodityPrice
* @return
*/
double settlement(double commodityPrice);
}
具体策略类
java
/**
* 具体策略
* 优惠券
*/
public class CouponStrategy implements ShoppingStrategy{
private double coupon;
/**
* 优惠券价格
* @param coupon
*/
public CouponStrategy(double coupon){
this.coupon = coupon;
}
@Override
public double settlement(double commodityPrice) {
return commodityPrice - coupon;
}
}
java
/**
* 打折
*/
public class DiscountStrategy implements ShoppingStrategy{
/**
* 折扣
*/
private double discount;
public DiscountStrategy(double discount){
this.discount = discount;
}
@Override
public double settlement(double commodityPrice) {
return commodityPrice * discount;
}
}
java
/**
* 无折扣
*/
public class NoDiscountStrategy implements ShoppingStrategy{
@Override
public double settlement(double commodityPrice) {
return commodityPrice;
}
}
上下文
java
/**
* 上下文
*/
public class ShoppingStrategyContext {
private ShoppingStrategy shoppingStrategy;
public ShoppingStrategyContext(ShoppingStrategy shoppingStrategy){
this.shoppingStrategy = shoppingStrategy;
}
/**
* 结算
* @param price
* @return
*/
public double settlement(double price){
return shoppingStrategy.settlement(price);
}
}
测试
java
/**
* 测试类
*/
public class StrategyTest {
public static void main(String[] args) {
ShoppingStrategyContext shoppingStrategyContext1 = new ShoppingStrategyContext(new NoDiscountStrategy());
double settlement = shoppingStrategyContext1.settlement(500);
System.out.println("无折扣价格结算为:"+settlement);
ShoppingStrategyContext shoppingStrategyContext2 = new ShoppingStrategyContext(new DiscountStrategy(0.7));
double settlement2 = shoppingStrategyContext2.settlement(500);
System.out.println("打折价格结算为:"+settlement2);
ShoppingStrategyContext shoppingStrategyContext3 = new ShoppingStrategyContext(new CouponStrategy(100));
double settlement3 = shoppingStrategyContext3.settlement(500);
System.out.println("使用优惠券结算为:"+settlement3);
}
}
结果
3.优缺点
优点
-
满足开闭原则,当增加新的具体策略略时,不需要修改上 下文类的代码,上下文就可以引用新的具体策略的实例。
-
避免使用多重条件判断,如果不用策略模式可能会使用多重条件语句不利于维护,和工厂模式的搭配使用可以很好地消除代码if-else的多层嵌套。
缺点
-
策略类数量会增多,每个策略都是一个类,复用的可能性很小。
-
对外暴露了类所有的行为和算法,行为过多导致策略类膨胀。
4.使用场景
- 当需要在运行时根据不同的条件选择使用不同的算法或行为时。
- 当需要避免使用大量的条件语句来决定使用哪个算法时。
- 当需要使算法的变化独立于使用算法的客户时。
- 当需要让客户能够定义一系列行为中的一个作为算法时。
总结
策略模式在实际开发中非常有用,特别是在需要根据不同的业务规则动态选择算法的场景中。它提高了代码的灵活性和可扩展性,使得算法的变化不会影响到使用算法的客户。