委派模式(Delegate Pattern)
- 介紹:委派模式(Delegate Pattern)的基本作用就是負(fù)責(zé)任務(wù)的調(diào)度和分配任何摔寨,跟代理模式很像,可以看做是一種情況下的靜態(tài)代理的的全權(quán)代理,但是代理模式注重過程宙拉,而委派模式注重結(jié)果
不屬于 23 中涉及模式之一
屬于行為型模式笨触。
java中Delegate 結(jié)尾的一般都是委派懦傍,包含Dispatcher 也是(spring 中DispatcherServlet就是使用委派模式)
- 使用場景
- 一件事情(或一個(gè)請求)對象本身不知道怎樣處理,對象把請求交給其它對象來做
- 優(yōu)點(diǎn): 對內(nèi)隱藏實(shí)現(xiàn), 易于擴(kuò)展; 簡化調(diào)用芦劣。
- 缺點(diǎn):和靜態(tài)代理的一樣粗俱,當(dāng)如果員工和leader類拓展的時(shí)候容易膨脹,難于管理虚吟。
//現(xiàn)實(shí)生活中也常有委 派的場景發(fā)生源梭,例如:老板(Boss)給項(xiàng)目經(jīng)理(Leader)下達(dá)任務(wù)娱俺,項(xiàng)目經(jīng)理會(huì)根據(jù) 實(shí)際情況給每個(gè)員工派發(fā)工作任務(wù),
//待員工把工作任務(wù)完成之后废麻,再由項(xiàng)目經(jīng)理匯報(bào)工 作進(jìn)度和結(jié)果給老板荠卷。我們用代碼來模擬下這個(gè)業(yè)務(wù)場景
public class Boss {
public void command(String command,Leader leader){
leader.doing(command);
}
}
//實(shí)現(xiàn)一個(gè)接口,各自都有各自的工作
public interface ITarget {
public void doing(String command);
}
public class Leader implements ITarget {
private Map<String,ITarget> targets = new HashMap<String,ITarget>();
// 初始化,會(huì)什么需要項(xiàng)目經(jīng)理知道
public Leader() {
targets.put("加密",new TargetA());
targets.put("登錄",new TargetB());
}
//項(xiàng)目經(jīng)理自己不干活
public void doing(String command){
targets.get(command).doing(command);
}
}
public class TargetA implements ITarget {
@Override
public void doing(String command) {
System.out.println("我是員工A烛愧,我現(xiàn)在開始干" + command + "工作");
}
}
public class TargetB implements ITarget {
@Override
public void doing(String command) {
System.out.println("我是員工B油宜,我現(xiàn)在開始干" + command + "工作");
}
}
// 客戶端調(diào)用
public class DelegateTest {
public static void main(String[] args) {
//客戶請求(Boss)、委派者(Leader)怜姿、被被委派者(Target)
//委派者要持有被委派者的引用
//代理模式注重的是過程慎冤, 委派模式注重的是結(jié)果
//策略模式注重是可擴(kuò)展(外部擴(kuò)展),委派模式注重內(nèi)部的靈活和復(fù)用
//委派的核心:就是分發(fā)沧卢、調(diào)度蚁堤、派遣
//委派模式:就是靜態(tài)代理和策略模式一種特殊的組合
new Boss().command("登錄",new Leader());
//sout :我是員工B,我現(xiàn)在開始干登錄工作
}
}
策略模式(Strategy Pattern)
- 介紹:策略模式(Strategy Pattern)是指定義了算法家族但狭、分別封裝起來披诗,讓它們之間可以互 相替換,此模式讓算法的變化不會(huì)影響到使用算法的用戶
- 使用場景
- 假如系統(tǒng)中有很多類立磁,而他們的區(qū)別僅僅在于他們的行為不同呈队。
- 一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種。
- 優(yōu)點(diǎn)
- 策略模式符合開閉原則唱歧。
- 避免使用多重條件轉(zhuǎn)移語句宪摧,如 if...else...語句、switch 語句
- 使用策略模式可以提高算法的保密性和安全性颅崩。
- 缺點(diǎn):
- 客戶端必須知道所有的策略几于,并且自行決定使用哪一個(gè)策略類。
- 代碼中會(huì)產(chǎn)生非常多策略類沿后,增加維護(hù)難度沿彭。
// 以訂單支付為例
//支付渠道
public abstract class Payment {
//支付類型
public abstract String getName();
//查詢余額
protected abstract double queryBalance(String uid);
//扣款支付
public MsgResult pay(String uid, double amount) {
if(queryBalance(uid) < amount){
return new MsgResult(500,"支付失敗","余額不足");
}
return new MsgResult(200,"支付成功","支付金額:" + amount);
}
}
// 多種支付
public class AliPay extends Payment {
public String getName() {
return "支付寶";
}
protected double queryBalance(String uid) {
return 1998;
}
}
public class JDPay extends Payment {
public String getName() {
return "京東支付";
}
protected double queryBalance(String uid) {
return 998;
}
}
//........
// 支付策略管理
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "JdPay";
public static final String DEFAULT_PAY = ALI_PAY;
// ......
private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
static {
payStrategy.put(ALI_PAY,new AliPay());
payStrategy.put(JD_PAY,new JDPay());
// .......
}
public static Payment get(String payKey){
if(!payStrategy.containsKey(payKey)){
return payStrategy.get(DEFAULT_PAY);
}
return payStrategy.get(payKey);
}
}
// 支付完成以后的狀態(tài)
public class MsgResult {
private int code;
private Object data;
private String msg;
public MsgResult(int code, String msg, Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
public String toString(){
return ("支付狀態(tài):[" + code + "]," + msg + ",交易詳情:" + data);
}
}
//訂單
public class Order {
private String uid;
private String orderId;
private double amount;
// setget() \ constructron
//完美地解決了switch的過程,不需要在代碼邏輯中寫switch了
//更不需要寫if else if
public MsgResult pay(){
return pay(PayStrategy.DEFAULT_PAY);
}
public MsgResult pay(String payKey){
Payment payment = PayStrategy.get(payKey);
System.out.println("歡迎使用" + payment.getName());
System.out.println("本次交易金額為:" + amount + "得运,開始扣款...");
return payment.pay(uid,amount);
}
}
//客戶端調(diào)用
public class PayStrategyTest {
public static void main(String[] args) {
//省略把商品添加到購物車膝蜈,再從購物車下單
//直接從點(diǎn)單開始
Order order = new Order("1","20180311001000009",324.45);
//開始支付锅移,選擇微信支付熔掺、支付寶、銀聯(lián)卡非剃、京東白條置逻、財(cái)付通
//每個(gè)渠道它支付的具體算法是不一樣的
//基本算法固定的
//這個(gè)值是在支付的時(shí)候才決定用哪個(gè)值
System.out.println(order.pay(PayStrategy.ALI_PAY));
InstantiationStrategy
}
}
// TODO 策略模式 可以用以上的抽象類,也可以使用接口
//源碼中涉及: Comparator接口 Arrays.parallelSort \ TreeMap 構(gòu)造方法等
//策略模式還可以繼承使用,請看:InstantiationStrategy\SimpleInstantiationStrategy\CglibSubclassingInstantiationStrategy