十五 Java设计模式解析(策略模式)
2018-10-13 本文已影响0人
十丈_红尘
1️⃣概念
定义: 定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户;
类型 :行为型;
2️⃣适用场景
系统有很多类,而他们的区别仅仅在于他们的行为不同;
一个系统需要动态地在几种算法中选择一种;
3️⃣优点
符合开闭原则;
避免使用多重条件转移语句;
提高算法的保密性和安全性;
4️⃣缺点
客户端必须知道所有的策略类,并自行选择使用哪一个策略类;
会产生很多策略类;
5️⃣策略模式Coding
1 创建PromotionStrategy接口
public interface PromotionStrategy {
void doPromotion();
}
2 创建不同的策略实现类
/**
* 满减策略
*/
public class ManJianPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("满减促销,满200-20元");
}
}
-----------------------------------------------------------------------------------------------
/**
* 立减策略
*/
public class LiJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("立减促销,课程的价格直接减去配置的价格");
}
}
-----------------------------------------------------------------------------------------------
/**
* 返现策略
*/
public class FanXianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额存放到慕课网用户的余额中");
}
}
3 创建类PromotionActivity
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void executePromotionStrategy(){
promotionStrategy.doPromotion();
}
}
4 编写测试类
public class Test {
public static void main(String[] args) {
PromotionActivity promotionActivity618 = new PromotionActivity(new LiJianPromotionStrategy());
PromotionActivity promotionActivity1111 = new PromotionActivity(new FanXianPromotionStrategy());
promotionActivity618.executePromotionStrategy();
promotionActivity1111.executePromotionStrategy();
}
}
5 UML类图
6 但是这样的写法并不能消除if else这样的判断我们来测试一下
public class Test {
public static void main(String[] args) {
PromotionActivity promotionActivity = null;
String promotionKey = "LIJIAN";
if(StringUtils.equals(promotionKey,"LIJIAN")){
promotionActivity = new PromotionActivity(new LiJianPromotionStrategy());
}else if(StringUtils.equals(promotionKey,"FANXIAN")){
promotionActivity = new PromotionActivity(new FanXianPromotionStrategy());
}//......
promotionActivity.executePromotionStrategy();
}
}
从上边的实例中我们可以看到,这样的代码还是会出现很多的判断并且会在命中某个条件以后创建新的对象,现在我们队这个进行一下改进,结合工厂模式;
7 创建策略工厂PromotionStrategyFactory
public class PromotionStrategyFactory {
private static Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, PromotionStrategy>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.LIJIAN,new LiJianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN,new FanXianPromotionStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN,new ManJianPromotionStrategy());
}
private static final PromotionStrategy NON_PROMOTION = new EmptyPromotionStrategy();
private PromotionStrategyFactory(){
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
}
private interface PromotionKey{
String LIJIAN = "LIJIAN";
String FANXIAN = "FANXIAN";
String MANJIAN = "MANJIAN";
}
}
8 创建空策略EmptyPromotionStrategy实现类
public class EmptyPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("无促销活动");
}
}
9 编写新的测试类
public class Test {
public static void main(String[] args) {
String promotionKey = "MANJIANxxx";
PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
promotionActivity.executePromotionStrategy();
}
}
6️⃣策略模式源码解析(jdk+spring)
jdk : public interface Comparator<T>
Spring : Resource