Uber公司技術棧介紹 Uber(Uber Technologies,Inc.)中文譯作“優步”,是一家美國矽谷的科技公司。Uber在2009年,由加利福尼亞大學洛杉磯分校輟學生特拉維斯·卡蘭尼克和好友加勒特·坎普(Garrett Camp)創立。因旗下同名打車APP而名聲大噪。Uber已經進入中國 ...
1 模式的定義
代理模式是一種結構型設計模式,它允許一個對象(代理)充當另一個對象的介面,以控制對該對象的訪問。代理模式通常用於控制對真實對象的訪問,以實現一些額外的功能,例如延遲載入、許可權控制、日誌記錄等。這種模式屬於結構型設計模式,因為它關註對象之間的組合,以形成更大的結構。
代理模式有多種類型,包括靜態代理和動態代理。靜態代理在編譯時創建代理對象,而動態代理在運行時創建代理對象。代理模式的核心思想是通過引入一個代理對象來控制對真實對象的訪問,從而實現額外的功能,而不必修改真實對象的代碼。
2 舉例說明
為了更好地理解代理模式,讓我們看幾個日常生活中的簡單示例。
一個最典型的例子就是狐假虎威,狐狸就做了老虎的代理。
銀行代理。在銀行業務中,某些操作需要前往銀行分行才能完成,但人們不一定都會前往分行。因此,銀行通常設立代理機構,例如ATM(自動取款機)和線上銀行,允許客戶在不必親自前往分行的情況下進行銀行業務。
網路代理。防火牆和代理伺服器是網路中常見的代理示例。防火牆代理可以過濾和控制網路流量,而代理伺服器可以緩存和優化網路請求,提高網路性能。
租房中介。在房地產市場中,房屋租賃中介機構充當租客和房東之間的代理。中介機構幫助租客找到合適的房源,同時為房東管理租賃過程,收取一定的服務費。
電影票代理。線上電影票代理網站允許觀眾在不必親自前往電影院的情況下購買電影票。這些代理網站提供了方便的線上訂票和座位選擇功能。
社交媒體代理。在社交媒體上,一些名人或公眾人物可能雇佣社交媒體代理來管理他們的社交媒體賬戶。這些代理負責發佈內容、與粉絲互動,以代表名人或公眾人物維護其線上存在。
這些示例都展示了代理模式的核心思想:允許一個對象(代理)充當另一個對象(真實對象)的介面,以控制對真實對象的訪問,同時可以添加額外的功能或服務。這種模式在日常生活中有著廣泛的應用,以提供更便利的服務和更好的控制。
3 結構
代理模式的結構包括以下幾個關鍵部分:
Subject(主題):定義了真實對象和代理對象的共同介面,以確保代理對象可以替代真實對象。在示例中,ImageLoader 就是主題。
RealSubject(真實主題):代表真實對象,它是實際執行工作的類。在示例中,ImageLoader 是真實主題。
Proxy(代理):充當了真實主題的代理,實現了與真實主題相同的介面。它可以在執行任務前後添加額外的功能。在示例中,ImageLoaderProxy 是代理。
4 實現步驟
實現代理模式時,通常遵循以下步驟:
定義主題介面(Subject):這個介面應該包含真實主題和代理類都必須實現的方法。
創建真實主題類(RealSubject):這個類負責執行實際的工作,實現主題介面的方法。
創建代理類(Proxy):代理類實現了主題介面,並包含一個對真實主題對象的引用。它可以在調用真實主題的方法前後添加額外的邏輯。
在客戶端代碼中使用代理:客戶端代碼不直接與真實主題交互,而是通過代理對象來訪問真實主題。
5 代碼實現
假設我們有一個圖像載入器類 ImageLoader,它負責從磁碟或網路載入圖像並顯示在界面上。現在,我們想要在載入圖像之前檢查用戶的許可權以確保他們有權查看該圖像。
在這個示例中,我們可以創建一個代理類 ImageLoaderProxy,它充當了 ImageLoader 的介面。在代理類中,我們可以添加許可權檢查的邏輯,然後再調用真實的 ImageLoader 對象來載入圖像。
// 1. 定義主題介面
interface ImageLoader {
void displayImage();
}
// 2. 創建真實主題類
class RealImageLoader implements ImageLoader {
private String image;
public RealImageLoader(String image) {
this.image = image;
}
@Override
public void displayImage() {
System.out.println("Displaying image: " + image);
}
}
// 3. 創建代理類
class ImageLoaderProxy implements ImageLoader {
private RealImageLoader realImageLoader;
private String image;
private String user;
public ImageLoaderProxy(String image, String user) {
this.image = image;
this.user = user;
}
@Override
public void displayImage() {
// 在調用真實主題前檢查用戶許可權
if (user.equals("admin")) {
realImageLoader = new RealImageLoader(image);
realImageLoader.displayImage();
} else {
System.out.println("Access denied. You do not have permission to view this image.");
}
}
}
// 4. 在客戶端代碼中使用代理
public class Client {
public static void main(String[] args) {
ImageLoader imageLoader = new ImageLoaderProxy("image.jpg", "admin");
imageLoader.displayImage();
ImageLoader imageLoader2 = new ImageLoaderProxy("image.jpg", "user");
imageLoader2.displayImage();
}
}
6 典型應用場景
代理模式在軟體開發中有許多典型的應用場景,包括但不限於:
虛擬代理(Virtual Proxy):延遲載入。用於延遲載入大型資源,例如圖像或文件,以提高性能。虛擬代理只在需要時載入真實對象,而不是在初始化時載入。
遠程代理(Remote Proxy):遠程服務訪問。用於通過網路訪問遠程對象,隱藏了底層的網路通信細節。客戶端可以像調用本地對象一樣訪問遠程對象。
保護代理(Protection Proxy):許可權控制。用於控制對對象的訪問,確保只有合適的用戶或客戶端可以訪問真實對象。通常用於實現身份驗證和授權。
緩存代理(Cache Proxy):緩存管理。用於在訪問對象之前檢查緩存,以提高性能。如果請求的數據已存在於緩存中,代理會返回緩存的數據而不是重新載入。
日誌記錄代理(Logging Proxy):用於在調用真實對象的方法前後添加日誌記錄,以監控和記錄系統行為。
動態代理(Dynamic Proxy):運行時代理。用於在運行時創建代理對象,通常通過Java的反射機制實現。動態代理可以實現通用的代理邏輯,而不需要為每個介面或對象單獨創建代理類。
這些應用場景和功能分類展示了代理模式的靈活性和多樣性。根據具體的需求和情況,可以選擇使用代理模式的不同變體來實現所需的功能,從而提高代碼的可維護性和靈活性
7 優缺點
優點:
控制訪問:代理模式允許你控制對真實對象的訪問,可以添加額外的邏輯來滿足特定需求,如許可權控制、日誌記錄等。
提高性能:虛擬代理和緩存代理可以提高性能,延遲載入和緩存對象可以減少不必要的資源消耗。
松耦合:代理模式可以將客戶端與真實對象解耦,客戶端不需要直接訪問真實對象,從而降低了耦合度。
安全性:代理模式可以用於實現安全性控制,確保只有符合條件的用戶或客戶端可以訪問真實對象。
缺點:
複雜性增加:引入代理對象可能會增加代碼複雜性,特別是在涉及多個代理層的情況下。
性能開銷:在一些情況下,代理模式可能引入性能開銷,特別是在創建代理對象的開銷較大時。
8 類似模式
與代理模式類似的模式包括裝飾器模式和適配器模式。這些模式與代理模式有一些相似之處,但它們各自有不同的目的和應用場景。
裝飾器模式(Decorator Pattern)
裝飾器模式的主要目的是動態地為對象添加額外的功能,而不改變其介面。它通過將對象包裝在裝飾器類中來實現這一點。代理模式和裝飾器模式都允許你包裝對象並添加額外的功能。它們都通過組合實現,都有一個共同的介面,但其關註點不同。代理模式關註於控制訪問和添加額外邏輯,而裝飾器模式關註於動態添加功能,但不改變介面。
適配器模式(Adapter Pattern)
適配器模式的主要目的是將一個介面轉換為另一個介面,以便兩個不相容的介面可以協同工作。它通常涉及到兩個已存在的介面之間的適配。代理模式和適配器模式都涉及到包裝對象。然而,代理模式主要關註於控制對真實對象的訪問,而適配器模式主要關註於介面的轉換。
9 小結
代理模式是一種有用的設計模式,用於控制對真實對象的訪問並添加額外的功能。它在許多應用場景中都有廣泛的用途,包括許可權控制、延遲載入、性能優化等。通過引入代理對象,可以實現松耦合的設計,使系統更加靈活和可維護。然而,代理模式也需要謹慎使用,因為不當使用可能會引入複雜性和性能開銷。在實際開發中,要根據具體需求和場景來選擇是否使用代理模式以及何種類型的代理模式。希望本文能夠幫助你更好地理解代理模式的概念和應用。