轉(zhuǎn)自:http://m.itdecent.cn/p/3ea48ecd7178
1.策略模式簡(jiǎn)介
先了解一下策略模式的定義
策略模式: 定義一系列的算法, 把它們一個(gè)個(gè)封裝起來(lái), 并且使它們可相互替換。 本模式使得算法可獨(dú)立于使用它的客戶而變化
應(yīng)用場(chǎng)景: 旅游出行方式,固定算法,支付方式
spring中的體現(xiàn):Spring 中在實(shí)例化對(duì)象的時(shí)候用到 Strategy 模式, 在SimpleInstantiationStrategy 有使用
再來(lái)了解一下策略模式的uml圖,看圖中類(lèi)和接口之間的層次關(guān)系
可以發(fā)現(xiàn),每個(gè)具體策略的實(shí)現(xiàn)都實(shí)現(xiàn)了相同的接口或者父類(lèi),然后需要提供一個(gè)上下文來(lái)提供策略的引用

2.策略模式實(shí)例
問(wèn)題 :關(guān)于支付方式選擇的問(wèn)題
現(xiàn)在有一名客戶需要在微信支付和銀聯(lián)支付以及支付寶這三種支付方式中選擇一種支付方式來(lái)給訂單付款,當(dāng)選擇一種支付方式支付成功之后,會(huì)得到支付的具體信息是否支付成功,以及支付的金額是多少
分析問(wèn)題:
可以把微信支付、銀聯(lián)支付以及支付寶支付共同實(shí)現(xiàn)一個(gè)共同的支付的接口,該支付的返回結(jié)果為支付后狀態(tài),還需要模擬一個(gè)訂單類(lèi),讓客戶為這個(gè)訂單類(lèi)付款。至于這三種支付方式的如何選擇,可以讓客戶自己來(lái)選擇,可以通過(guò)一個(gè)枚舉類(lèi)型來(lái)讓客戶選擇。
具體的代碼實(shí)現(xiàn):
先給出支付狀態(tài)的代碼實(shí)現(xiàn)
/**
* @Project: spring
* @description: 支付后的狀態(tài)
* @author: sunkang
* @create: 2018-09-03 11:16
* @ModificationHistory who when What
**/
public class PayState {
//支付后的狀態(tài)碼
private int code;
//支付后的消息提示
private String msg;
//代表誰(shuí)支付的
private String uid ;
//支付的數(shù)據(jù)大小
private Object data;
public PayState(int code, String msg, String uid, Object data) {
this.code = code;
this.msg = msg;
this.uid = uid;
this.data = data;
}
@Override
public String toString() {
return "payState{" +
"code=" + code +
", msg='" + msg + '\'' +
", uid='" + uid + '\'' +
", data=" + data +
'}';
}
}
支付方式的接口
/**
* @Project: spring
* @description: 支付方式的接口
* @author: sunkang
* @create: 2018-09-03 11:14
* @ModificationHistory who when What
**/
public interface Payment {
/**
*
* @param uid 表示人的uid
* @param amount 表示支付的金額
* @return
*/
PayState pay(String uid, double amount);
}
支付寶支付的實(shí)現(xiàn)
/**
* @Project: spring
* @description: 支付寶支付
* @author: sunkang
* @create: 2018-09-03 11:22
* @ModificationHistory who when What
**/
public class AliPay implements Payment{
@Override
public PayState pay(String uid, double amount) {
System.out.println("歡迎來(lái)到支付寶支付");
System.out.println("開(kāi)始查詢余額,開(kāi)始扣款");
return new PayState(200,"支付成功",uid,amount);
}
}
銀聯(lián)閃付的實(shí)現(xiàn)
/**
* @Project: spring
* @description: 銀聯(lián)閃付的實(shí)現(xiàn)
* @author: sunkang
* @create: 2018-09-03 11:26
* @ModificationHistory who when What
**/
public class UnionPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("歡迎來(lái)到銀聯(lián)閃付");
System.out.println("開(kāi)始查詢余額,開(kāi)始扣款");
return new PayState(200,"支付成功",uid,amount);
}
}
微信支付的實(shí)現(xiàn)
/**
* @Project: spring
* @description: 微信支付的實(shí)現(xiàn)
* @author: sunkang
* @create: 2018-09-03 11:24
* @ModificationHistory who when What
**/
public class WechatPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("歡迎來(lái)到微信支付");
System.out.println("開(kāi)始查詢余額,開(kāi)始扣款");
return new PayState(200,"支付成功",uid,amount);
}
}
提供一個(gè)支付方式的選擇器
/**
* @Project: spring
* @description: 支付方式的一個(gè)context
* @author: sunkang
* @create: 2018-09-03 11:29
* @ModificationHistory who when What
**/
public enum PayType {
ALI_PAY(new AliPay()),
WECHAT_PAY(new AliPay()),
UNION_PAY(new AliPay());
private Payment payment ;
PayType(Payment payment) {
this.payment = payment;
}
public Payment get(){
return this.payment;
}
}
模擬一個(gè)訂單類(lèi)
/**
* @Project: spring
* @description: 模擬一個(gè)訂單類(lèi)
* @author: sunkang
* @create: 2018-09-03 11:27
* @ModificationHistory who when What
**/
public class Order {
private String uid;
private String oid;
private double amount;
public Order(String uid, String oid, double amount) {
this.uid = uid;
this.oid = oid;
this.amount = amount;
}
//為訂單支付
public PayState pay(PayType payType){
return payType.get().pay(uid,amount);
}
}
策略模式測(cè)試
/**
* @Project: spring
* @description: 策略模式測(cè)試
* @author: sunkang
* @create: 2018-09-03 11:33
* @ModificationHistory who when What
**/
public class StrategyTest {
public static void main(String[] args) {
Order order = new Order("1","order101",43.23);
//比如選擇阿里支付
PayState payState = order.pay(PayType.ALI_PAY);
System.out.println(payState);
}
}
測(cè)試結(jié)果
