? ??????????????????????????????????設(shè)計模式(分類)????????設(shè)計模式(六大原則)? ?
? ? 創(chuàng)建型(5種)????????工廠方法?????????抽象工廠模式????????單例模式????????建造者模式????????原型模式
? ? 結(jié)構(gòu)型(7種)????????適配器模式????????裝飾器模式????????代理模式??????????????外觀模式??????橋接模式????????組合模式? ? ? ?享元模式
? ? 行為型(11種)???????策略模式????????模板方法模式????????觀察者模式????????迭代器模式????????責(zé)任鏈模式????????命令模式
????????????????????????????????? ?備忘錄模式 ?????????狀態(tài)模式 ?????????訪問者模式????????中介者模式? ??
代理模式(Proxy Pattern)是一種結(jié)構(gòu)型設(shè)計模式,它為其他對象(被代理對象)提供一個代理對象,并由代理對象控制對被代理對象的訪問。代理模式通過引入代理對象來間接訪問目標對象,從而實現(xiàn)對目標對象的增強、控制訪問權(quán)限、遠程訪問等功能。代理模式的關(guān)鍵在于代理類與目標類具有相同的接口,客戶端可以透明地使用代理對象代替目標對象。
模式結(jié)構(gòu)
代理模式通常包含以下角色:
抽象主題(Subject):定義了目標對象和代理對象共有的接口,這樣在任何使用目標對象的地方都可以使用代理對象。
真實主題(Real Subject):也稱為被代理對象,實現(xiàn)了抽象主題接口,包含具體業(yè)務(wù)邏輯。
代理(Proxy):也實現(xiàn)了抽象主題接口,其內(nèi)部持有真實主題的引用。代理對象在實現(xiàn)接口方法時,可以選擇調(diào)用真實主題的方法,也可以在調(diào)用前后添加額外的操作,如預(yù)處理、后處理、訪問控制、日志記錄等。
工作原理
- 客戶端:通過代理對象來調(diào)用目標對象的方法,對客戶端而言,代理對象與真實主題對象在接口上是透明的,客戶端無需關(guān)心具體使用的是哪個對象。
- 代理:實現(xiàn)了與真實主題相同的接口,內(nèi)部持有真實主題的引用。代理對象在接收到客戶端請求時,可以選擇直接調(diào)用真實主題的方法,也可以在調(diào)用前后添加額外的操作。
- 真實主題:實現(xiàn)了抽象主題接口,包含具體的業(yè)務(wù)邏輯。在代理模式中,真實主題通常不直接暴露給客戶端,而是通過代理對象間接訪問。
代理模式的分類
靜態(tài)代理:代理類在編譯時就確定,由程序員創(chuàng)建代理類或使用工具生成。靜態(tài)代理的優(yōu)點是直觀、簡單,缺點是需要為每個具體主題都創(chuàng)建一個對應(yīng)的代理類,增加了代碼量和維護成本。
動態(tài)代理:代理類在運行時動態(tài)生成,如Java中的JDK動態(tài)代理和CGLIB庫。動態(tài)代理的優(yōu)點是可以減少代碼量,只需要編寫一個通用的代理類生成器,適用于需要為大量類生成代理的情況。
優(yōu)缺點
優(yōu)點
- 職責(zé)清晰:代理對象與真實主題對象職責(zé)明確,代理對象負責(zé)控制訪問、增強功能等,真實主題對象專注于業(yè)務(wù)邏輯。
- 擴展性好:通過代理模式可以方便地添加新的功能,如訪問控制、日志記錄等,而無需修改真實主題。
- 保護真實主題:通過代理對象可以隱藏真實主題的實現(xiàn)細節(jié),提供額外的安全性和控制。
缺點
- 增加復(fù)雜性:引入代理對象會使系統(tǒng)變得更復(fù)雜,增加了額外的類和對象關(guān)系。
- 性能損耗:代理模式可能會帶來一定的性能損耗,尤其是在代理對象執(zhí)行額外操作的情況下。
適用場景
- 需要為對象增加額外功能:如添加日志、事務(wù)管理、訪問控制等,而又不想修改對象本身。
- 需要對對象的訪問進行控制:如遠程訪問、延遲加載、資源優(yōu)化等。
- 需要隱藏對象的復(fù)雜性:通過代理對象對外提供簡潔的接口,隱藏真實主題的復(fù)雜實現(xiàn)。
代碼示例(以Java為例,展示靜態(tài)代理)
// 抽象主題(接口)
interface Image {
void display();
}
// 真實主題(被代理對象)
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading image from disk: " + fileName);
}
@Override
public void display() {
System.out.println("Displaying image: " + fileName);
}
}
// 代理
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();
}
}
// 客戶端代碼
public class Client {
public static void main(String[] args) {
Image proxyImage = new ProxyImage("large-image.jpg");
proxyImage.display(); // 輸出:Loading image from disk: large-image.jpg, Displaying image: large-image.jpg
System.out.println("\nDisplaying image again:");
proxyImage.display(); // 輸出:Displaying image: large-image.jpg
}
}
在這個Java示例中:
Image
接口作為抽象主題,定義了顯示圖像的方法。RealImage
類是需要被代理的真實主題,實現(xiàn)了Image
接口,包含了從磁盤加載圖像和顯示圖像的業(yè)務(wù)邏輯。ProxyImage
類作為代理,實現(xiàn)了Image
接口,內(nèi)部持有RealImage
對象的引用。ProxyImage
在實現(xiàn)display()
方法時,首先檢查RealImage
對象是否已經(jīng)加載,如果沒有則先加載圖像,然后調(diào)用RealImage
的display()
方法顯示圖像。這樣實現(xiàn)了延遲加載的功能,只有在真正需要顯示圖像時才從磁盤加載,提高了性能。
客戶端代碼創(chuàng)建ProxyImage
對象,并通過代理對象調(diào)用display()
方法,實現(xiàn)了對真實主題對象的延遲加載??蛻舳藷o需關(guān)心代理對象的實現(xiàn)細節(jié),只需面向Image
接口編程。文章來源地址http://www.zghlxwxcb.cn/news/detail-856843.html
?代碼示例(以Python為例)
# 抽象主題(接口)
class Image:
def display(self):
raise NotImplementedError("Subclasses must implement this method")
# 真實主題(被代理對象)
class RealImage(Image):
def __init__(self, filename):
self.filename = filename
self.load_from_disk()
def load_from_disk(self):
print(f"Loading image from disk: {self.filename}")
def display(self):
print(f"Displaying image: {self.filename}")
# 代理
class ProxyImage(Image):
def __init__(self, filename):
self.filename = filename
self.real_image = None
def display(self):
if not self.real_image:
self.real_image = RealImage(self.filename)
self.real_image.display()
# 客戶端代碼
def main():
proxy_image = ProxyImage("large-image.jpg")
proxy_image.display() # 輸出:Loading image from disk: large-image.jpg, Displaying image: large-image.jpg
print("\nDisplaying image again:")
proxy_image.display() # 輸出:Displaying image: large-image.jpg
if __name__ == "__main__":
main()
在這個Python示例中:文章來源:http://www.zghlxwxcb.cn/news/detail-856843.html
Image
類作為抽象主題,定義了顯示圖像的display()
方法。RealImage
類是需要被代理的真實主題,繼承自Image
類,包含了從磁盤加載圖像和顯示圖像的業(yè)務(wù)邏輯。ProxyImage
類作為代理,同樣繼承自Image
類,內(nèi)部持有RealImage
對象的引用。ProxyImage
在實現(xiàn)display()
方法時,首先檢查RealImage
對象是否已經(jīng)加載,如果沒有則先加載圖像,然后調(diào)用RealImage
的display()
方法顯示圖像。這樣實現(xiàn)了延遲加載的功能,只有在真正需要顯示圖像時才從磁盤加載,提高了性能。
客戶端代碼創(chuàng)建ProxyImage
對象,并通過代理對象調(diào)用display()
方法,實現(xiàn)了對真實主題對象的延遲加載。客戶端無需關(guān)心代理對象的實現(xiàn)細節(jié),只需面向Image
接口編程。
到了這里,關(guān)于設(shè)計模式- 代理模式(Proxy Pattern)結(jié)構(gòu)|原理|優(yōu)缺點|場景|示例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!