策略模式
策略模式(Strategy Pattern):是指定义了不同的算法逻辑,并将不同的算法分别封装起来,让它们之间可以互相替换,使用者可以使用任意一种算法。策略模式可以让算法逻辑发生变化时不会影响到使用算法逻辑的用户,一般常用来改造代码中大量的 if 逻辑。示例:日常生活中,我们经常使用的支付方式(支付宝、微信、云闪付等),就相当于是策略模式中的算法,我们使用任意一种支付方式都不会影响最终的结果。那么,我们就以支付为例来看看怎么使用策略模式。
package cn.liangyy.strategy;
import java.math.BigDecimal;
/**
* 顶层的策略接口
*/
public interface IPayStrategy {
/**
* 支付
* @param money 支付金额
* @return
*/
boolean pay(int money);
/**
* 查询余额
* @return
*/
BigDecimal queryBalance();
}
复制代码
package cn.liangyy.strategy;
import java.math.BigDecimal;
/**
* 支付宝支付类
*/
public class ALiPayStrategy implements IPayStrategy {
/**
* 支付
*
* @param money 支付金额
* @return
*/
@Override
public boolean pay(int money) {
System.out.println("支付宝支付成功!");
return true;
}
/**
* 查询余额
*
* @return
*/
@Override
public BigDecimal queryBalance() {
System.out.println("支付宝余额为 20 元!");
return new BigDecimal("20");
}
}
复制代码
package cn.liangyy.strategy;
import java.math.BigDecimal;
/**
* 微信支付类
*/
public class WeChatPayStrategy implements IPayStrategy {
/**
* 支付
*
* @param money 支付金额
* @return
*/
@Override
public boolean pay(int money) {
System.out.println("微信支付成功!");
return true;
}
/**
* 查询余额
*
* @return
*/
@Override
public BigDecimal queryBalance() {
System.out.println("微信余额为 30 元!");
return new BigDecimal("30");
}
}
复制代码
package cn.liangyy.strategy;
/**
* 策略模式-测试类
*/
public class TestPayStrategy {
public static void main(String[] args) {
//支付类型
String pay = "aliPay";
IPayStrategy payStrategy = null;
//根据不同的支付类型,选择不同的支付种类
if (pay.equals("aliPay")){
payStrategy = new ALiPayStrategy();
}else if (pay.equals("wechatPay")){
payStrategy = new WeChatPayStrategy();
}
payStrategy.pay(10);
payStrategy.queryBalance();
}
}
复制代码
上面是策略模式的一个简单写法,但是上面的写法存在一个很大的问题,就是例如有很多策略,那么我们的 if 判断就会变得很庞大,这明显不利于维护,所以需要再对上面的例子进行改造。
package cn.liangyy.strategy;
/**
* 枚举类
* 用来维护所有的策略和key值对应关系
*/
public enum PayEnum {
AliPay("aliPay",new ALiPayStrategy()),
WechatPay("wechatPay",new WeChatPayStrategy());
private String key;
private IPayStrategy value;
PayEnum(String key, IPayStrategy value) {
this.key = key;
this.value = value;
}
public static IPayStrategy getValue(String key){
//遍历枚举类
for (PayEnum payEnum : PayEnum.values()){
if (payEnum.key.equals(key)){
return payEnum.value;
}
}
//如果没有合适的key就默认使用支付宝支付
return new ALiPayStrategy();
}
}
复制代码
package cn.liangyy.strategy;
public class TestPayStrategy2 {
public static void main(String[] args) {
IPayStrategy iPayStrategy = PayEnum.getValue("aliPay");
iPayStrategy.pay(10);
iPayStrategy.queryBalance();
}
}
复制代码
对比前后两种方式,很显然,第二种写法更加优雅方便,在实际中应用场景更多。
策略模式适用场景同一个系统假如存在场景可能有很多分支,而每次又只可能是一种分支,那么这种情况就非常适合使用策略模式来编码,彼此策略之间独立又可互相替换。
策略模式优点
策略模式缺点
评论