策略模式(Strategy Pattern)
在策略模式中,一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为型设计模式
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象,策略对象改变context对象的执行算法
介绍
意图:定义一系列的算法,把它们封装起来,并且使他们可以相互替换
主要解决:在有多种算法相似的情况下,使用if else带来的复杂和难以维护
如何使用:一个系统有许多类,区分他们的只是他们直接的行为
如何解决:将这些算法封装成一个个的类,任意调换
关键代码:实现同一个接口
实际应用实例:比如消息的推送(微信公众号,短信,钉钉...),支付方式的不同,结算不同(微信支付,支付宝支付,银行卡支付...)Java AWT中的LayOutManger
优点:算法自由切换,减少if else复杂逻辑,扩展性良好
缺点:策略类会增多,所有的策略类都需要对外暴露
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
demo
1:枚举类,形如你有哪些支付方式,哪些推送消息的方式
public enum ReChargeEnum {
E_Bink(1,"网银"),
MOBILE(3,"手机充值"),
PAYPLAY(4,"支付宝"),
WEIXING(5,"微信"),
BUSI_ACCOUNT(2,"商户");
private int value;
private String descreption;
ReChargeEnum(int value, String descreption) {
this.value = value;
this.descreption = descreption;
}
public static ReChargeEnum valueOf(int value){
for (ReChargeEnum reChargeEnum:
ReChargeEnum.values()) {
if (reChargeEnum.value==value){
return reChargeEnum;
}
}
return null;
}
get set...
2:策略的接口,比如是付款,那他们统一的工作都是付款,只是支付方式不一样,即为实现了不一样
/**
* 支付
*/
public interface StrategyService {
Double calReCharge(Double charge,ReChargeEnum reChargeEnum);
}
3:具体的支付方式(此处就不一一列举)实现支付接口
public class WeiXinPayServiceImpl implements StrategyService {
@Override
public Double calReCharge(Double charge, ReChargeEnum reChargeEnum) {
return charge*0.85;
}
}
4:一个生产这些支付方式的工厂类
public class StrategyFactory {
private static StrategyFactory strategyFactory=new StrategyFactory();
public StrategyFactory() {
}
public static Map<Integer,StrategyService> strategyServiceMap=new HashMap<>();
static {
strategyServiceMap.put(ReChargeEnum.WEIXING.getValue(),new WeiXinPayServiceImpl());
strategyServiceMap.put(ReChargeEnum.E_Bink.getValue(),new BUSIPayServiceImpl());
...
...
}
public static StrategyService create(Integer type){
return strategyServiceMap.get(type);
}
public static StrategyFactory getStrategyFactory(){
return strategyFactory;
}
}
5:一个对外提供算法的简单类Context
public class Context {
private StrategyService strategyService;
public double calCharge(double charge,Integer type){
strategyService= StrategyFactory.getStrategyFactory().create(type);
return strategyService.calReCharge(charge,ReChargeEnum.valueOf(type));
}
public StrategyService getStrategyService() {
return strategyService;
}
public void setStrategyService(StrategyService strategyService) {
this.strategyService = strategyService;
}
}
6:使用案例
public static void main(String[] args) {
Context context=new Context();
double calCharge = context.calCharge(100d, 5);
System.out.println("微信支付:"+calCharge);
double calCharge1 = context.calCharge(100d, 1);
System.out.println("网银支付:"+calCharge1);
}
不用再像这样
public class Example {
public Double calRecharge(Double charge ,RechargeTypeEnum type ){
if(type.equals(RechargeTypeEnum.E_BANK)){
return charge*0.85;
}else if(type.equals(RechargeTypeEnum.BUSI_ACCOUNTS)){
return charge*0.90;
}else if(type.equals(RechargeTypeEnum.MOBILE)){
return charge;
}else if(type.equals(RechargeTypeEnum.CARD_RECHARGE)){
return charge+charge*0.01;
}else{
return null;
}
}
}