策略模式 : 定义了 算法家族 , 分别 封装起来 , 让它们之间 , 可以 相互替换 , 此模式 让 算法的变化 不会影响到 使用算法的用户 ;
将 不同的算法 , 封装到 不同的类 中 , 让它们之间可以 相互替换 , 使用算法的用户 即 应用层 , 感知不到 算法已经被替换了 ;
实际的业务场景 :
策略模式类型 : 行为型 ;
策略模式适用场景 :
策略模式优点 :
策略模式缺点 :
策略模式与工厂模式 :
策略模式与状态模式 :
设计模式选择 :
策略模式 一般不是独立使用的 , 可能需要结合单例 , 工厂模式 , 享元模式 等多个设计模式 , 一起实现业务逻辑 ;
如果遇到大量的 if … else … 可以考虑是否可以抽象 对象 以及 行为 , 将其封装成策略模式 ;
如果一个对象的行为经常变化 , 扩展性要求比较高 , 也可以考虑使用策略模式 ;
业务场景 :
商场促销活动 : 促销是商品的一个行为 , 促销行为 , 设置多个促销行为 , 将其封装到类中 ;
package strategy;
/**
* 促销策略接口
* 所有的促销策略 , 都要实现该接口
*/
public interface PromotionStrategy {
/**
* 促销活动
*/
void doPromotion();
}
package strategy;
/**
* 满减促销策略
* 满 100 减 20
*/
public class ManJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("满减促销 , 满 100 减 20");
}
}
package strategy;
/**
* 返现促销策略
* 购买后返优惠券
*/
public class FanXianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返现促销 , 返优惠券 10 元");
}
}
package strategy;
/**
* 空的促销策略
* 为了防止空指针
*/
public class EmptyPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("原价出售");
}
}
package strategy;
import java.util.HashMap;
/**
* 促销策略工厂
*/
public class PromotionStrategyFactory {
private static HashMap<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN, new ManJianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN, new FanXianPromotionStrategy());
}
/**
* 构造函数不能被外界访问
*/
private PromotionStrategyFactory() {
}
/**
* 根据传入的键值获取相应的促销策略
* @param promotionKey
* @return
*/
public static PromotionStrategy getPromotionStrategy(String promotionKey) {
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy != null ? promotionStrategy : new EmptyPromotionStrategy();
}
/**
* 使用这种方式声明常量 , 可以起到逻辑上分组的作用
*/
public interface PromotionKey {
String MANJIAN = "ManJian";
String FANXIAN = "FanXian";
}
}
package strategy;
/**
* 促销活动
*/
public class PromotionActivity {
/**
* 促销策略 , 通过构造器注入
*/
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
/**
* 执行促销策略
*/
public void executePromotionStrategy() {
this.promotionStrategy.doPromotion();
}
}
package strategy;
public class Main {
public static void main(String[] args) {
// 获取促销策略
PromotionStrategy promotionStrategy = PromotionStrategyFactory.
getPromotionStrategy(PromotionStrategyFactory.PromotionKey.FANXIAN);
// 创建促销活动 , 并执行促销策略
PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
// 执行促销策略
promotionActivity.executePromotionStrategy();
}
}