人生的游戏不在于拿了一副好牌,而在于怎样去打好坏牌,世上没有常胜将军,勇于超越自我者才能得到最后的奖杯。
1. 策略模式
定义
策略模式又叫政策模式,它是将定义的算法家族,分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。
可以避免多重分支的if 。。。。else 和switch语句。
属于行为型模式
适用场景
假如系统中有很多的类,而他们的区别仅仅在于他们的行为不同。
一个系统需要动态地在几种算法中选择一种
需要屏蔽算法规则
优点
策略模式符合开闭原则
避免使用多出个的条件转移语句,如if … else 、switch语句
使用策略模式可以提高算法的保密性和安全性。
缺点
客户端必须要知道所有的策略,并且自己决定执行使用哪一个策略类
代码中会产生非常多的策略类,增加维护难度
2. 优惠券案例
网购中有很多优惠策略,那么这种场景非常适合策略模式
public interface IPromotionStrategy {
void doPromotion();
}
public class CashbackStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("返现,直接打款到支付宝账号");
}
}
public class CouponStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("使用优惠券抵扣");
}
}
public class EmptyStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("无优惠");
}
}
public class GroupBuyStrategy implements IPromotionStrategy {
public void doPromotion() {
System.out.println("5人团购, 可以优惠");
}
}
public class PromotionFactory {
private static Map<String, IPromotionStrategy> PROMIOTIONS = new HashMap<String, IPromotionStrategy>();
private static final IPromotionStrategy EMPTY = new EmptyStrategy();
static {
PROMIOTIONS.put(PromotionKey.CASHBACK, new CashbackStrategy());
PROMIOTIONS.put(PromotionKey.COUPON, new CouponStrategy());
PROMIOTIONS.put(PromotionKey.GROUPBUY, new GroupBuyStrategy());
}
public static IPromotionStrategy getPromiotion(String promotion) {
if (PROMIOTIONS.containsKey(promotion)) {
return PROMIOTIONS.get(promotion);
}
return EMPTY;
}
private interface PromotionKey {
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUPBUY = "GROUPBUY";
}
public static Set<String> getPromotionKeys(){
return PROMIOTIONS.keySet();
}
}
public class Test {
public static void main(String[] args) {
Set<String> promotions = PromotionFactory.getPromotionKeys();
System.out.println("所有支付方式:" + promotions.toString());
String promotion = "COUPON";
IPromotionStrategy strategy = PromotionFactory.getPromiotion(promotion);
strategy.doPromotion();
promotion = "CASHBACK";
strategy = PromotionFactory.getPromiotion(promotion);
strategy.doPromotion();
}
}
所有支付方式:[CASHBACK, COUPON, GROUPBUY]
使用优惠券抵扣
返现,直接打款到支付宝账号
3. 支付案例
最典型的策略模式就是支付。现在网购支付方式多种多样,不同的支付方式都有不同背后算法。
public class MsgResult {
private int code;
private String msg;
private Object data;
public MsgResult(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
@Override
public String toString() {
return "MsgResult{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
public abstract class Payment {
public MsgResult pay(String uid, double amount) {
if (queryBlance(uid) < amount) {
return new MsgResult(500, "支付失败", "余额不足");
}
return new MsgResult(0, "支付成功", "支付金额: " + amount);
}
protected abstract double queryBlance(String uid);
protected abstract String getName();
}
public class AliPay extends Payment {
@Override
public double queryBlance(String uid) {
return 1000;
}
@Override
public String getName() {
return "支付宝";
}
}
public class JDPay extends Payment {
@Override
public double queryBlance(String uid) {
return 900;
}
@Override
public String getName() {
return "京东支付";
}
}
public class YunShanPay extends Payment {
@Override
public double queryBlance(String uid) {
return 500;
}
@Override
public String getName() {
return "云闪付";
}
}
public class PayStrategy {
public static final String ALI_PAY = "ALI_PAY";
public static final String JD_PAY = "JD_PAY";
public static final String YUNSHAN_PAY = "YUNSHAN_PAY";
public static final String DEFAULT_PAY = ALI_PAY;
private static Map<String, Payment> strategy = new HashMap<String, Payment>();
static {
strategy.put(ALI_PAY, new AliPay());
strategy.put(JD_PAY, new JDPay());
strategy.put(YUNSHAN_PAY, new YunShanPay());
}
public static Payment getPayment(String payKey) {
if (strategy.containsKey(payKey)) {
return strategy.get(payKey);
}
return strategy.get(DEFAULT_PAY);
}
}
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid, String orderId, double amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public MsgResult pay() {
return pay(PayStrategy.DEFAULT_PAY);
}
public MsgResult pay(String payKey) {
Payment payment = PayStrategy.getPayment(payKey);
System.out.println("欢迎使用: " + payment.getName() + "支付");
System.out.println("本次交意金额: " + amount + "开始支付");
return payment.pay(uid, amount);
}
}
public class Test {
public static void main(String[] args) {
Order order = new Order("1", "202012160909", 999);
System.out.println(order.pay());
System.out.println(order.pay(PayStrategy.JD_PAY));
System.out.println(order.pay(PayStrategy.YUNSHAN_PAY));
}
}
欢迎使用: 支付宝支付
本次交意金额: 999.0开始支付
MsgResult{code=0, msg='支付成功', data=支付金额: 999.0}
欢迎使用: 京东支付支付
本次交意金额: 999.0开始支付
MsgResult{code=500, msg='支付失败', data=余额不足}
欢迎使用: 云闪付支付
本次交意金额: 999.0开始支付
MsgResult{code=500, msg='支付失败', data=余额不足}
感谢您阅读本文,如果您觉得文章写的对您有用的话,请您点击上面的“关注”,点个赞,这样您就可以持续收到《JAVA架构师之路》的最新文章了。文章内容属于自己的一点点心得,难免有不对的地方,欢迎在下方评论区探讨,你们的关注是我创作优质文章的动力。