設計模式-委派模式

語言: CN / TW / HK

theme: channing-cyan

# 七大軟體設計原則
# 設計模式-工廠模式
# 設計模式-單例模式
# 設計模式-原型模式
# 設計模式-策略模式
# 設計模式-責任鏈模式
# 設計模式-建造者模式
# 設計模式-深度分析代理模式
# 設計模式-門面模式
# 設計模式-裝飾器模式
# 設計模式-享元模式
# 設計模式-組合模式
# 設計模式-介面卡模式
# 設計模式-橋接模式

委派模式(Delegate Pattern)又叫委託模式,是一種面向物件的設計模式,允許物件組合實現與 繼承相同的程式碼重用。它的基本作用就是負責任務的呼叫和分配任務,是一種特殊的靜態代理,可以理 解為全權代理,但是代理模式注重過程,而委派模式注重結果。委派模式屬於行為型模式,不屬於 GOF 23 種設計模式中。

通俗點講就是有兩個物件參與(兩個物件協同)處理同一個請求,接受請求的物件將請求委託給另一個物件來處理。

委派模式的UML類圖

image.png 可以發現和靜態代理類的類圖一樣,所以也叫做特殊的靜態代理,唯一的區別就是關注點不一樣,一個是過程一個是結果

程式碼如下: public interface Task { void doSomething(); } public class ConcreteA implements Task{ @Override public void doSomething() { System.out.println("ConcreteA doSomething"); } } public class ConcreteB implements Task{ @Override public void doSomething() { System.out.println("ConcreteB doSomething"); } } ``` public class Delegate implements Task{ private Task task = new ConcreteA();

@Override
public void doSomething() {
    task.doSomething();
}

public void toA(){
    task = new ConcreteA();
}

public void toB(){
    task = new ConcreteB();
}

} public class Test { public static void main(String[] args) { Delegate delegate = new Delegate(); delegate.doSomething(); delegate.toB(); delegate.doSomething(); } } ```

程式碼示例

舉個典型的例子:路由,我們知道路由的作用就是在不同網段之間轉發資料的,當路由器接受到一個訊息的時候她會根據訊息頭部中的資訊找出對應網段再根據自己的路由表找到對應的機器再轉發給實際接收者,這裡面路由就是一個委託者角色而註冊到這個路由中的計算機則是實際執行任務的角色(實際接收訊息的角色)
訊息體: ``` @Data public class Message { private String content; private String targetIp; private String sourceIp;

public Message(String content, String targetIp, String sourceIp) {
    this.content = content;
    this.targetIp = targetIp;
    this.sourceIp = sourceIp;
}

} 1. 首先抽象出任務的角色 public interface IMessage { void receiveMessage(Message message); } 3. 具體任務實現物件 @Data public class ComputerA implements IMessage{ private String ip = "192.168.88.7"; @Override public void receiveMessage(Message message) { System.out.println("ComputerA處理訊息:" + message.getContent()); } } @Data public class ComputerB implements IMessage{ private String ip = "192.168.88.8"; @Override public void receiveMessage(Message message) { System.out.println("ComputerB處理訊息:" + message.getContent()); } @Data public class ComputerC implements IMessage{ private String ip = "192.168.88.9"; @Override public void receiveMessage(Message message) { System.out.println("Computerc處理訊息:" + message.getContent()); } } 5. 委託者角色 public class Route implements IMessage{ private final Map routeTable= new HashMap<>(); public Route(){ ComputerA computerA = new ComputerA(); ComputerB computerB = new ComputerB(); ComputerC computerC = new ComputerC(); routeTable.put(computerA.getIp(),computerA); routeTable.put(computerB.getIp(),computerB); routeTable.put(computerC.getIp(),computerC); }

    @Override
    public void receiveMessage(Message message) {
        if(routeTable.containsKey(message.getTargetIp())){
            routeTable.get(message.getTargetIp()).receiveMessage(message);
        }
    }
}
```
這裡用了策略模式配合使用
  1. 客戶端呼叫 public class Test { public static void main(String[] args) { Message message = new Message("hello","192.168.88.7","192.168.88.100"); Route route = new Route(); route.receiveMessage(message); } }
  2. 列印結果 image.png
  3. UML類圖 image.png

原始碼中的應用

jvm在載入類的時候使用的就是雙親委派,就是在載入類之前會先找父類,如果存在父類則繼續找父類的父類知道找到最頂級的父類然後載入返回即可,如果沒有父類則載入類然後返回,具體原始碼我們可以看一下 ClassLoader這個類: image.png image.png

委派模式優缺點

優點: 1. 通過任務委派能夠將一個大型的任務細化。 2. 將應用相關的內容與框架完全分離開 3. 避免過多的子類以及子類與父類的耦合 4. 通過委託傳遞訊息機制實現分層解耦

缺點:
任務委派方式需要根據任務的複雜程度進行不同的改變,在任務比較複雜的情況下可能需要進行多 重委派,容易造成紊亂。