設計模式之代理模式

1、什麼是代理模式(Porxy)

  概念:代理模式就是爲其餘對象提供一種代理以控制對這個對象的訪問。安全

  現實生活中也有不少行爲吻合代理模式。好比店外賣,客戶在APP上下單後,店長會接單。這個時候店長能夠選擇本身去送這份外賣,也能夠委託送餐員代理店長去送這份外賣。固然店長是能夠本身送,但店長送了外賣店就沒人看着了,而讓送餐員代理送外賣就不會這樣了。這裏很顯然店長是對象本尊(Subject),送餐員是代理對象(Proxy ),代理對象中有店長給的訂單信息,好比送到哪裏,幾點以前要送到,這就說明代理對象中須要包含本尊。下面根據實際代碼來講明代理模式和非代理的具體實現。ide

2、模式對比

一、非代理模式

非代理模式即店長本身送,無須委託送餐員代理送。即直接建立本尊對象並訪問本尊方法,沒有中間的代理對象。測試

本尊代碼this

public class ShopKeeper {

    //客戶信息
    private Consumer consumer;
    
    public ShopKeeper(Consumer consumer){
        this.consumer = consumer;
    }
    
    //外賣訂單信息
    public void send(){
        System.out.println(consumer.getConName() + "的訂單,店長本身送,送到膠東路520弄,11:30以前送達...");
    }
    
}

客戶代碼spa

public class Consumer {

    private String conName;
    
    public Consumer(String conName){
        this.conName = conName;
    }

    public String getConName() {
        return conName;
    }
}

客戶端測試代碼代理

public class Show {

    public static void main(String[] args) {
        Consumer consumer = new Consumer("Tom");
        ShopKeeper shopKeeper = new ShopKeeper(consumer);
        shopKeeper.send();
    }
    
}

這樣店長和客戶的代碼就耦合在一塊兒,不利於後期維護升級。再者店長和客戶原本就不須要相互包含,他們之間是無狀態的。像不少pub/sub的中間件,好比dubbo,activeMQ等等,他們都是基於消息的發佈的訂閱機制,生產者和消費者之間沒有必要有狀態交互,你消費者掛了我生產者仍是繼續生產消息,互不影響,其實不少技術都是想通的,這裏和代理模式就和相似。下面來看看代理模式是怎麼處理的。code

二、代理模式

提供了一個共有的送外賣接口中間件

public interface Send {

    void sendName();
    void sendTime();
    void sendAddress();
    
}

店長本尊對象,實現了共有的送外賣接口。對象

/**
 * 店長對象(本尊)須要實現Send接口
 * @author user
 */
public class ShopKeeper implements Send{

    private Consumer consumer;
    
    public ShopKeeper(Consumer consumer){
        this.consumer = consumer;
    }
    
    @Override
    public void sendName() {
        System.out.print(consumer.getConName() + "的訂單,");
    }
    
    @Override
    public void sendTime() {
        System.out.print("12:00以前送達,");
    }

    @Override
    public void sendAddress() {
        System.out.print("送到長島路520弄,由代理對象配送...");
    }

新增了代理對象,代理對象須要包含本尊,而且也要實現送外賣(Send)接口blog

/**
 * 代理對象也須要實現Send接口
 * @author user
 *
 */
public class ProxySend implements Send{

    private ShopKeeper shopKeeper;
    
    public ProxySend(Consumer consumer){
        this.shopKeeper = new ShopKeeper(consumer);
    }
    
    @Override
    public void sendName() {
        shopKeeper.sendName();
    }

    @Override
    public void sendTime() {
        shopKeeper.sendTime();
    }

    @Override
    public void sendAddress() {
        shopKeeper.sendAddress();
    }

}

客戶對象沒有變化

public class Consumer{
    
    private String conName;

    public String getConName() {
        return conName;
    }

    public void setConName(String conName) {
        this.conName = conName;
    }
}

客戶端測試代碼

public class Show {

    public static void main(String[] args) {
        
        Consumer consumer = new Consumer();
        consumer.setConName("外賣張");
        ProxySend proxy = new ProxySend(consumer);
        proxy.sendName();
        proxy.sendTime();
        proxy.sendAddress();
        
    }
    
}

看輸出

外賣張的訂單,12:00以前送達,送到長島路520弄...

這樣代理對象就幫本尊完成了任務,能夠看到客戶端的代碼變化很大,客戶端根本不知道本尊的存在,由於在客戶端代碼中至始至終都沒有看到本尊對象的建立,連實例都沒有,這其實就是代理對象的做用之一,隱藏本尊。

三、代理模式基本結構

Subject類,定義了RealSubject和Proxy的共用接口,這樣就在任何使用RealSubject的地方均可以使用Proxy,這裏使用抽象類

public abstract class Subject {

    public abstract void request(); 
    
}

RealSubject類,定義了Proxy所表明的真是實體

public class RealSubject extends Subject {

    @Override
    public void request() {
        System.out.println("真實的請求");
    }

}

Proxy類,保存了一個引用使得代理對象能夠訪問實體對象,並提供一個與Subject的接口相同的接口,這樣代理就能夠用來代理實體。

public class Proxy extends Subject{

    RealSubject realSubject;
    
    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();
    }

}

客戶端代碼

public class Show {

    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
    
}

測試結果

真實的請求

四、UML圖

3、總結

代理模式通常用在一下幾種場合。一、遠程代理,也就是爲了一個對象在不一樣的地址空間提供局部表明。這樣能夠隱藏一個對象存在於不一樣地址空間的事實。二、虛擬代理,是根據須要建立開銷很大的對象。經過它來存放實例化須要很長時間的真實對象。三、安全代理,用來控制真實對象訪問是的權限。四、智能指引,是指當前調用真實的對象時,代理處理另一些事情。因此代理模式還算比較經常使用的。

相關文章
相關標籤/搜索