java ----代理模式

我們先來分析代理這個詞。

一、代理

代理是英文 Proxy 翻譯過來的。我們在生活中見到過的代理,大概最常見的就是朋友圈中賣面膜的同學了。

她們從廠家拿貨,然後在朋友圈中宣傳,然後賣給熟人。

這裏寫圖片描述

按理說,顧客可以直接從廠家購買產品,但是現實生活中,很少有這樣的銷售模式。一般都是廠家委託給代理商進行銷售,顧客跟代理商打交道,而不直接與產品實際生產者進行關聯。

所以,代理就有一種中間人的味道。

接下來,我們說說軟件中的代理模式。

二、代理模式

代理模式是面向對象編程中比較常見的設計模式。
這裏寫圖片描述

這是常見代理模式常見的 UML 示意圖。

需要注意的有下面幾點:

  1. 用戶只關心接口功能,而不在乎誰提供了功能。上圖中接口是 Subject。
  2. 接口真正實現者是上圖的 RealSubject,但是它不與用戶直接接觸,而是通過代理。
  3. 代理就是上圖中的 Proxy,由於它實現了 Subject 接口,所以它能夠直接與用戶接觸。
  4. 用戶調用 Proxy 的時候,Proxy 內部調用了 RealSubje

三、代理模式的實例程序

我們將創建一個 Image 接口和實現了 Image 接口的實體類。ProxyImage 是一個代理類,減少 RealImage 對象加載的內存佔用。

ProxyPatternDemo,我們的演示類使用 ProxyImage 來獲取要加載的 Image 對象,並按照需求進行顯示。

代理模式的 UML 圖

步驟 1

創建一個接口。

Image.java

public interface Image {
   void display();
}

步驟 2

創建實現接口的實體類。

RealImage.java

public class RealImage implements Image {
 
   private String fileName;
 
   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }
 
   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }
 
   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

ProxyImage.java

public class ProxyImage implements Image{
 
   private RealImage realImage;
   private String fileName;
 
   public ProxyImage(String fileName){
      this.fileName = fileName;
   }
 
   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}

步驟 3

當被請求時,使用 ProxyImage 來獲取 RealImage 類的對象。

ProxyPatternDemo.java

public class ProxyPatternDemo {
   
   public static void main(String[] args) {
      Image proxyImage = new ProxyImage("test_10mb.jpg");
 
      // 圖像將從磁盤加載
      proxyImage.display(); 
      System.out.println("");
      // 圖像不需要從磁盤加載
      proxyImage.display();  
   }
}

步驟 4

執行程序,輸出結果:

Loading test_10mb.jpg
Displaying test_10mb.jpg

Displaying test_10mb.jpg

四、代理模式分析

代理模式中的角色:

  • Subject(主體)
    Subject角色定義了使proxy和realsubject角色之間具有一致性的接口。這個接口提供了一個使用的好處,就是client不必卻分它使用的是代理對象還是真實對象。
    對應實例中Printable角色

  • Proxy(代理人)
    Proxy角色會盡量處理來自Client角色的請求。只有當自己不能處理的時候,就交給工作交給真實對象。代理對象只有在有必要時纔會生成真實的對象。
    實例中對應的是PrinterProxy對象。

  • RealSubject(真實對象)
    就是實際完成工作的對象,對應實例中的Printer對象。

代理模式的類圖:

img

  • 用代理人來提升速度
    關鍵就在於延遲初始化。
    我們可以等到需要使用到真實對象的功能才初始化。這樣的好處就是可以提升性能。從我們的實例中可能看不出這個優勢,假設我們有一個大型系統,如果我們都在系統啓動的時候,把所有功能初始化,所有實例初始化,那麼顯然系統的啓動將會變得很慢。但如果我們採用代理模式,那麼就會在必須的時候,在初始化對象。這樣就加快了系統的啓動速度。
  • 代理和委託
    其實我們學習了那麼多設計模式,是不是感覺委託簡直無處不在。幾乎每個設計模式都會用到委託,代理模式也不意外,就是代理了對象委託了真實對象。
    因爲委託可以是對象之間發生聯繫,互相調用。所以委託在很多設計模式中都存在。


參考文章 :
  • https://www.jianshu.com/p/5ab7672b935f
  • https://blog.csdn.net/briblue/article/details/73928350
  • https://www.runoob.com/design-pattern/proxy-pattern.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章