介紹
策略模式(Strategy Pattern)是指定義了算法家族、分別封裝起來,讓它們之間可以互 相替換,此模式讓算法的變化不會影響到使用算法的用戶。
優點
1、策略模式符合開閉原則。
2、避免使用多重條件轉移語句,如 if...else...語句、switch 語句
3、使用策略模式可以提高算法的保密性和安全性。
缺點
1、客戶端必須知道所有的策略,並且自行決定使用哪一個策略類。
2、代碼中會產生非常多策略類,增加維護難度。
使用場景
1、假如系統中有很多類,而他們的區別僅僅在於他們的行爲不同。
2、一個系統需要動態地在幾種算法中選擇一種。
使用建議
實際的開發中使用的比較多,多重if...else...可以考慮使用這種方式。
具體實現
(實例一)選擇不同的支付方式:
類圖
代碼
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code, String msg,Object data ) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "支付狀態:[" +code+"]" + "支付金額:" + data + "響應信息:" + msg ;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_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 PayState pay(){
return pay(PayStrategyFactory.PayTypeEnum.Default.getType());
}
public PayState pay(String payTypeKey){
Payment payment=PayStrategyFactory.getPayType(payTypeKey);
System.out.println("歡迎使用 " + payment.getName() + " 支付");
System.out.println("本次交易金額爲:"+amount+",開始扣款...");
return payment.pay(uid,amount);
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
/**
* 支付渠道
*/
public abstract class Payment {
/**
* 支付方式
* @return
*/
public abstract String getName();
/**
* 查詢餘額
* @param uid
* @return
*/
public abstract double queryBalance(String uid);
public PayState pay(String uid,double amount){
if(queryBalance(uid)<amount){
return new PayState(500,"支付失敗","餘額不足");
}
return new PayState(200,"支付成功","支付金額:"+amount);
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class AliPay extends Payment {
@Override
public String getName() {
return "支付寶";
}
@Override
public double queryBalance(String uid) {
return 900;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class JDPay extends Payment {
@Override
public String getName() {
return "京東百度";
}
@Override
public double queryBalance(String uid) {
return 100;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class UnionPay extends Payment {
@Override
public String getName() {
return "銀聯支付";
}
@Override
public double queryBalance(String uid) {
return 120;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class WechatPay extends Payment{
@Override
public String getName() {
return "微信支付";
}
@Override
public double queryBalance(String uid) {
return 256;
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
import java.util.HashMap;
import java.util.Map;
public class PayStrategyFactory {
private PayStrategyFactory() {}
private static Map <String, Payment> paymentMap=new HashMap <>();
static {
paymentMap.put(PayTypeKey.Default,new AliPay());
paymentMap.put(PayTypeKey.AliPay,new AliPay());
paymentMap.put(PayTypeKey.JDPay,new JDPay());
paymentMap.put(PayTypeKey.UnionPay,new UnionPay());
paymentMap.put(PayTypeKey.WechatPay,new WechatPay());
}
public static Payment getPayType(String payType){
Payment payment=paymentMap.get(payType);
return null==payment?paymentMap.get("Default"):payment;
}
//通過接口實現----工廠類外部不方便使用
private interface PayTypeKey{
String AliPay="AliPay";
String JDPay="JDPay";
String UnionPay="UnionPay";
String WechatPay="WechatPay";
String Default="Default";
}
//通過枚舉實現----工廠類外部可方便的使用
public enum PayTypeEnum{
AliPay("AliPay"),
JDPay("JDPay"),
UnionPay("UnionPay"),
WechatPay("WechatPay"),
Default("Default"),
;
private String type;
PayTypeEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.order_pay;
public class Test {
public static void main(String[] args) {
Order order=new Order("11","3210000005679000009",10);
PayState state=order.pay(PayStrategyFactory.PayTypeEnum.JDPay.getType());
System.out.println(state.toString());
}
}
(實例二)不同的促銷打折方式:
類圖
代碼
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 促銷抽象類
*/
public interface PromotionStrategy {
void doPromotion();
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 優惠券
*/
public class CouponStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("領取優惠券,下單享受優惠券折扣");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 返現優惠
*/
public class CashBackStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返現促銷,返回的金額轉到支付寶賬戶");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class EmptyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("沒有促銷活動");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
/**
* 團購優惠
*/
public class GroupBuyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("拼團,滿20人成團,全團享受團購價");
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute(){
promotionStrategy.doPromotion();
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
import java.util.HashMap;
import java.util.Map;
public class PromotionStrategyFactory {
private PromotionStrategyFactory(){}
private static final PromotionStrategy defaultPromotion=new EmptyStrategy();
private static Map <String,PromotionStrategy> promotionStrategyMap=new HashMap<>();
static {
promotionStrategyMap.put(PromotionKey.CASHBACK,new CashBackStrategy());
promotionStrategyMap.put(PromotionKey.COUPON,new CouponStrategy());
promotionStrategyMap.put(PromotionKey.GROUTBUY,new GroupBuyStrategy());
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy =promotionStrategyMap.get(promotionKey);
return null==promotionStrategy?defaultPromotion:promotionStrategy;
}
private interface PromotionKey {
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUTBUY = "GROUTBUY";
}
}
package com.knowledge.system.software_design_pattern.strategy_pattern.promotion;
public class Test {
/*
1.替換 if...else switch...case
2.一個系統需要動態的在幾種算法中選擇一種
* */
public static void main(String[] args) {
System.out.println("策略模式測試");
//第一種,完全和實際脫軌
/*
PromotionActivity activity=new PromotionActivity(new GroupBuyStrategy());
PromotionActivity activity1=new PromotionActivity(new CashBackStrategy());
activity.execute();
activity1.execute();*/
//第二種,冗餘了很多的if...else
/* PromotionActivity activity=null;
String promotionKey="COUPON";
if(promotionKey.equals("COUPON")) {
activity = new PromotionActivity(new CouponStrategy());
}
if(promotionKey.equals("CASHBACK")) {
activity = new PromotionActivity(new CashBackStrategy());
}
if(promotionKey.equals("GROUPBUY")) {
activity = new PromotionActivity(new GroupBuyStrategy());
}
activity.execute();*/
//爲簡化代碼,引入單例模式與簡單工廠,繼續簡化代碼------史上最強策略模式
String promotionKey = "CASHBACK";
PromotionStrategy strategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
strategy.doPromotion();
}
}