策略模式
經過學習後整理
策略模式(Strategy Pattern)是指定義了算法家族、分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化不會影響到使用算法的用戶。
策略模式的應用場景
1、假如系統中有很多類,而他們的區別僅僅在於他們的行爲不同。
2、一個系統需要動態地在幾種算法中選擇一種。
用策略模式實現選擇支付方式的業務場景
//支付完成後返回狀態
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "支付狀態{" + code +
", 交易詳情=" + data +
", 返回信息'" + msg + '\'' +
'}';
}
}
public abstract class Payment {
//獲取支付類型
public abstract String getName();
//查詢餘額
protected abstract double getBalance(String uid);
//扣款支付
public PayState pay(String uid, Double amount) {
if (getBalance(uid) < amount) {
return new PayState(500, "支付失敗", "餘額不足");
}
return new PayState(200, "支付成功", "支付金額:" + amount);
}
}
public class Alipay extends Payment {
@Override
public String getName() {
return "支付寶支付";
}
@Override
protected double getBalance(String uid) {
return 200;
}
}
public class Weixinpay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double getBalance(String uid) {
return 300;
}
}
public class Unionpay extends Payment {
@Override
public String getName() {
return "銀聯支付";
}
@Override
protected double getBalance(String uid) {
return 100;
}
}
//支付策略
public class Paystrategy {
public static final String ALI_PAY = "Alipay";
public static final String WEIXIN_PAY = "Weixinpay";
public static final String UNION_PAY = "Unionpay";
private static Map<String, Payment> map = new HashMap<String, Payment>();
static {
map.put(ALI_PAY, new Alipay());
map.put(WEIXIN_PAY, new Weixinpay());
map.put(UNION_PAY, new Unionpay());
}
public static Payment get(String payKey) {
if (!map.containsKey(payKey)) {
//沒有此支付方式,正常需要返回錯誤信息
return null;
}
return map.get(payKey);
}
}
public class Order {
private String uid;
private String OrderId;
private Double amount;
public Order(String uid, String orderId, Double amount) {
this.uid = uid;
OrderId = orderId;
this.amount = amount;
}
public PayState pay(String payKey) {
Payment payment = Paystrategy.get(payKey);
System.out.println("使用" + payment.getName() + ",支付金額爲:" + amount);
PayState payState = payment.pay(uid, amount);
return payState;
}
}
public static void main(String[] args) {
Order order = new Order("1232", "1232", 132.2);
PayState pay = order.pay(Paystrategy.ALI_PAY);
System.out.println(pay);
}
}
策略模式的優缺點
優點:
1、策略模式符合開閉原則。
2、避免使用多重條件轉移語句,如if…else…語句、switch 語句
3、使用策略模式可以提高算法的保密性和安全性。
缺點:
1、客戶端必須知道所有的策略,並且自行決定使用哪一個策略類。
2、代碼中會產生非常多策略類,增加維護難度。