策略模式原理分析
- 设计模式系列总览
- 什么是策略模式
- 策略模式使用场景
- 策略模式示例
- 策略模式类图展示
- 策略模式的优点
- 策略模式的缺点
设计模式系列总览
设计模式 | 飞机票 |
三大工厂模式 | |
策略模式 | |
委派模式 | |
模板方法模式 | |
观察者模式 | |
单例模式 | |
原型模式 | |
代理模式 | |
装饰者模式 | |
适配器模式 | |
建造者模式 | |
责任链模式 | |
享元模式 | |
组合模式 | |
门面模式 | |
桥接模式 | |
中介者模式 | |
迭代器模式 | |
状态模式 | 登机入口 |
解释器模式 | 登机入口 |
备忘录模式 | |
命令模式 | |
访问者模式 | |
软件设计7大原则和设计模式总结 |
什么是策略模式
策略模式(Strategy Pattern)属于GoF23种设计模式之一,策略模式是指定义了不同的算法逻辑,并将其封装起来,让它们之间可以互相替换,此模式可以让算法逻辑发生变化时不会影响到使用算法逻辑的用户。策略模式可以用于改造代码中的if…else逻辑
策略模式使用场景
同一个系统中存在不同的逻辑算法,而彼此之间在不同场景中需要实现动态替换,如:支付方式,可以选择:支付宝,微信,银联等,彼此之间就可以相互替换,再如商场打折促销活动,有双11活动,双12活动,彼此之间可以相互替换
策略模式示例
首先策略模式必须有一个策略接口,然后根据不同业务逻辑新建不同的实现类完成具体逻辑。
接下来笔者就以支付为例来实现一个策略模式的例子,如下定义了一个顶级策略接口。
1、创建一个策略接口
import java.math.BigDecimal;
public interface PayStrategry {
boolean pay(int money);//支付
BigDecimal queryBalance(String accountNo);//查询余额
}
2、接下来定义2个实现类示例
import com.zwx.design.pattern.PayStrategy;
import java.math.BigDecimal;
public class AliPayStrategy implements PayStrategy {
@Override
public boolean pay(int money) {
System.out.println("支付宝支付成功");
return true;
}
@Override
public BigDecimal queryBalance(String accountNo) {
System.out.println("支付宝余额10元");
return new BigDecimal(10);
}
}
import com.zwx.design.pattern.PayStrategy;
import java.math.BigDecimal;
public class WechatPayStrategy implements PayStrategy {
@Override
public boolean pay(int money) {
System.out.println("微信支付成功");
return true;
}
@Override
public BigDecimal queryBalance(String accountNo) {
System.out.println("微信余额10元");
return new BigDecimal(10);
}
}
3、接下来我们来测试一下
import com.zwx.design.pattern.impl.AliPayStrategy;
import com.zwx.design.pattern.impl.WechatPayStrategy;
public class TestPayStrategy {
public static void main(String[] args) {
String pay = "aliPay";
PayStrategy payStrategy = null;
if(pay.equals("aliPay")){
payStrategy = new AliPayStrategy();
}else if(pay.equals("wechatPay")){
payStrategy = new WechatPayStrategy();
}
payStrategy.pay(10);
payStrategy.queryBalance("XXX");
}
}
实际业务中一般这个支付类型需要依赖于前端传递。
上面业务中我们可通过枚举类或者工厂设计模式进行改造。
接下来笔者通过枚举类的实现方式来改造一下测试方法:
(1)、首先定义一个枚举类,用于创建不同的策略
import com.zwx.design.pattern.impl.AliPayStrategy;
import com.zwx.design.pattern.impl.WechatPayStrategy;
public enum PayEnum {
AliPay("aliPay",new AliPayStrategy()),
WechatPay("wechatPay",new WechatPayStrategy());
private String key;
private PayStrategy value;
PayEnum(String key, PayStrategy value) {
this.key = key;
this.value = value;
}
public static PayStrategy getValue(String key){
for (PayEnum payEnum : PayEnum.values()){
if (payEnum.key.equals(key)){
return payEnum.value;
}
}
return new AliPayStrategy();//没有合适key则默认阿里支付
}
}
(2)、接下来测试类改写如下:
import com.zwx.design.pattern.impl.AliPayStrategy;
import com.zwx.design.pattern.impl.WechatPayStrategy;
public class TestPayStrategy {
public static void main(String[] args) {
String pay = "aliPay";
PayStrategy payStrategy = PayEnum.getValue(pay);
payStrategy.pay(10);
payStrategy.queryBalance("XXX");
}
}
这么改写之后,如果以后新增了其他支付方式只需要再枚举类中新怎过一种枚举类型并且实现自定义支付逻辑之后,其他代码就无需变更
策略模式类图展示
策略模式的优点
1、策略模式符合开闭原则
2、避免使用多重条件转移语句,如if…else…、switch等循环语句
3、使用策略模式可以提高逻辑算法的保密性和安全性
策略模式的缺点
1、使用者必须知道所有的策略,并且自行决定使用哪一个策略类
2、代码中会产生非常多策略类,增加维护难度