本设计模式资料源于慕课网,讲师:Geely 《Java设计模式精讲 Debug方式+内存分析》,本人作为自己手打整理作为学习的归纳总结。
一,模式介绍
1,定义和类型
- 定义:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化不会影响到使用算法的用户
- if…else…
- 类型:行为型
2,适用场景
- 系统有很多类,而他们的区别仅仅在于他们的行为不同
- 一个系统需要动态地在几种算法中悬着一种
3,优点
- 开闭原则
- 避免使用多重条件转移语句
- 提高算法的保密性和安全性
4,缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类
- 产生很多策略类
5,相关设计模式
- 策略模式和工厂模式
- 策略模式和状态模式
二,代码演示
- 业务场景
慕课网上的课程需要进行促销,而促销的方式有很多种,客户端需要在其中选择一种执行
促销方式接口类以及各种实现类
package com.try1.design.behavioral.strategy;
public interface PromotionStrategy {
void doPromotion();
}
返现策略
package com.try1.design.behavioral.strategy;
public class FanXianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("执行返现策略,返现200万");
}
}
立减策略
package com.try1.design.behavioral.strategy;
public class LiJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("执行立减策略,直接就减200万");
}
}
满减策略
package com.try1.design.behavioral.strategy;
public class ManJianPromotionStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("执行满减策略,满200-20");
}
}
无促销策略
package com.try1.design.behavioral.strategy;
public class NonPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("无促销策略");
}
}
策略接口的直接赋值和执行类
package com.try1.design.behavioral.strategy;
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void executePromotionStrategy(){
promotionStrategy.doPromotion();
}
}
策略工厂类(根据客户端的输入判断具体使用哪一个策略)
package com.try1.design.behavioral.strategy;
import java.util.HashMap;
import java.util.Map;
public class PromotionStrategyFactory {
private static Map<String,PromotionStrategy> promotionStrategyMap=new HashMap<String, PromotionStrategy>();
static {
promotionStrategyMap.put(PromotionKey.LIJIAN,new LiJianPromotionStrategy());
promotionStrategyMap.put(PromotionKey.FANXIAN,new FanXianPromotionStrategy());
promotionStrategyMap.put(PromotionKey.MANJIAN,new ManJianPromotionStrategy());
}
private static final PromotionStrategy NON_PROMOTION=new NonPromotionStrategy();
private PromotionStrategyFactory(){
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy=promotionStrategyMap.get(promotionKey);
return promotionStrategy==null?NON_PROMOTION:promotionStrategy;
}
private interface PromotionKey{
String LIJIAN="LIJIAN";
String MANJIAN="MANJIAN";
String FANXIAN="FANXIAN";
}
}
测试类(注释的地方是不使用工厂的方法)
package com.try1.design.behavioral.strategy;
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();
/**
* method2
*/
// PromotionActivity promotionActivity=null;
// String PromotionKey="LIJIAN";
//
// if (PromotionKey=="LIJIAN"){
// promotionActivity=new PromotionActivity(new LiJianPromotionStrategy());
// }else if(PromotionKey=="FANXIAN"){
// promotionActivity=new PromotionActivity(new FanXianPromotionStrategy());
// }//.....
/*
*method3
*/
String promotionKey="LIJIAN";
PromotionActivity promotionActivity=new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
promotionActivity.executePromotionStrategy();
}
}
三,总结
- 从被注释的测试类中可以看出,在不使用工厂类的情况下,需要不断进行判断,然后再决定要执行的策略类,这样既浪费内存,执行速度也慢,显然是不符合要求的。
- 策略模式让我联系到了享元模式中的 map ,同样是提前设置好要执行的一些类,在具体执行的时候选择某一个想要的对象。