實例講解Java設(shè)計模式編程中如何運用代理模式
定義:
Provide a surrogate or placeholder for another object to control access to it.
為其他對象一種代理以控制對這個對象的訪問。
一般描述:
一般包含的三個角色:抽象主題、具體主題、代理主題。
- 抽象主題:是一個抽象類或接口,是一個普通的業(yè)務(wù)類型定義。
- 具體主題:業(yè)務(wù)邏輯的具體執(zhí)行者
- 代理角色:負(fù)責(zé)對真是角色的應(yīng)用,把所有抽象主題類定義的方法限制委托給真實主題角色實現(xiàn)。
通用類圖:

通用代碼:
package Proxy;
//抽象主題類:
public interface Subject {
public void doSomething();
}
package Proxy;
//具體主題類
public class RealSubject implements Subject{
@Override
public void doSomething() {
System.out.println("業(yè)務(wù)邏輯...");
}
}
package Proxy;
//代理主題類
public class Proxy implements Subject{
private Subject sub = null;
@Override
public void doSomething() {
this.sub.doSomething();
}
public Proxy(Subject sub){
this.sub = sub;
}
}
package Proxy;
//客戶端
public class Client {
public static void main(String[] args) {
Subject realsub = new RealSubject();
Subject proxy = new Proxy(realsub);
proxy.doSomething();
}
}
優(yōu)點:
1. 職責(zé)清晰
2. 高擴展
代理模式的擴展:
普通代理:
具體主題類對高層透明,在代理主題類中構(gòu)造具體主題類
代碼實現(xiàn):
package GeneralProxy;
public interface Subject {
public void doSomething();
}
package GeneralProxy;
public class RealSubject implements Subject{
private String name = null;
@Override
public void doSomething() {
System.out.println(this.name + "被代理,正在執(zhí)行業(yè)務(wù)邏輯...");
}
public RealSubject(Subject proxy,String name) throws Exception{
if(proxy == null){
throw new Exception("無法創(chuàng)建被代理對象");
}else{
this.name = name;
}
}
}
package GeneralProxy;
public class Proxy implements Subject{
private Subject realsub = null;
public Proxy(String name) {
try {
realsub = new RealSubject(this, name);
} catch (Exception e) {
e.printStackTrace();
}
}
public void doSomething() {
realsub.doSomething();
}
}
package GeneralProxy;
public class Client {
public static void main(String[] args) {
//普通代理
Subject proxy = new Proxy("張三");
proxy.doSomethaing();
}
}
強制代理:
必須通過訪問具體主題類獲取代理主題類的對象,然后用代理主題類控制訪問
代碼實現(xiàn):
package MustProxy;
public interface Subject {
public void doSomething();
public Subject getProxy();
}
package MustProxy;
public class RealSubject implements Subject{
private String name = null;
private Subject proxy = null;
@Override
public void doSomething() {
if(isProxy()){
System.out.println(this.name + "被代理,正在執(zhí)行業(yè)務(wù)邏輯...");
}else{
System.out.println("請先訪問代理...");
}
}
public RealSubject(String name) {
this.name = name;
}
public Subject getProxy() {
proxy = new Proxy(this);
return this.proxy;
}
private boolean isProxy(){
if(this.proxy == null){
return false;
}else{
return true;
}
}
}
package MustProxy;
public class Proxy implements Subject{
private Subject realSub = null;
public Proxy(Subject realSub) {
this.realSub = realSub;
}
public void doSomething() {
this.realSub.doSomething();
}
public Subject getProxy() {
return this;
}
}
package MustProxy;
public class Client {
public static void main(String[] args) {
Subject realSub = new RealSubject("張三");
realSub.doSomething();
Subject proxy = realSub.getProxy();
proxy.doSomething();
}
}
應(yīng)用場景
現(xiàn)實世界中,秘書就相當(dāng)于一個代理,老板開會,那么通知員工開會時間、布置會場、會后整理會場等等開會相關(guān)工作就可以交給秘書做,老板就只需要開會就行了,不需要親自做那些事。同理,在我們程序設(shè)計中也可使用代理模式來將由一系列無關(guān)邏輯組合在一起的代碼進行解耦合,比如業(yè)務(wù)代碼中的日志代碼就可以在代理中進行。Spring的AOP就是典型的動態(tài)代理應(yīng)用。
代理模式的應(yīng)用形式
(1)遠(yuǎn)程代理(Remote Proxy) -可以隱藏一個對象存在于不同地址空間的事實。也使得客戶端可以訪問在遠(yuǎn)程機器上的對象,遠(yuǎn)程機器可能具有更好的計算性能與處理速度,可以快速響應(yīng)并處理客戶端請求。
(2)虛擬代理(Virtual Proxy) – 允許內(nèi)存開銷較大的對象在需要的時候創(chuàng)建。只有我們真正需要這個對象的時候才創(chuàng)建。
(3)寫入時復(fù)制代理(Copy-On-Write Proxy) – 用來控制對象的復(fù)制,方法是延遲對象的復(fù)制,直到客戶真的需要為止。是虛擬代理的一個變體。
(4)保護代理(Protection (Access)Proxy) – 為不同的客戶提供不同級別的目標(biāo)對象訪問權(quán)限
(5)緩存代理(Cache Proxy) – 為開銷大的運算結(jié)果提供暫時存儲,它允許多個客戶共享結(jié)果,以減少計算或網(wǎng)絡(luò)延遲。
(6)防火墻代理(Firewall Proxy) – 控制網(wǎng)絡(luò)資源的訪問,保護主題免于惡意客戶的侵害。
(7)同步代理(SynchronizationProxy) – 在多線程的情況下為主題提供安全的訪問。
(8)智能引用代理(Smart ReferenceProxy) - 當(dāng)一個對象被引用時,提供一些額外的操作,比如將對此對象調(diào)用的次數(shù)記錄下來等。
(9)復(fù)雜隱藏代理(Complexity HidingProxy) – 用來隱藏一個類的復(fù)雜集合的復(fù)雜度,并進行訪問控制。有時候也稱為外觀代理(Façade Proxy),這不難理解。復(fù)雜隱藏代理和外觀模式是不一樣的,因為代理控制訪問,而外觀模式是不一樣的,因為代理控制訪問,而外觀模式只提供另一組接口。
- 詳解JAVA設(shè)計模式之代理模式
- Java設(shè)計模式之動態(tài)代理模式實例分析
- Java設(shè)計模式之靜態(tài)代理模式實例分析
- 23種設(shè)計模式(7) java代理模式
- java設(shè)計模式筆記之代理模式
- java設(shè)計模式學(xué)習(xí)之代理模式
- java設(shè)計模式-代理模式(實例講解)
- Java設(shè)計模式之代理模式與裝飾模式實例詳解
- Java設(shè)計模式之代理模式_動力節(jié)點Java學(xué)院整理
- java設(shè)計模式之代理模式(Porxy)詳解
- java設(shè)計模式—靜態(tài)代理模式(聚合與繼承方式對比)
- 詳解設(shè)計模式中的proxy代理模式及在Java程序中的實現(xiàn)
- Java使用設(shè)計模式中的代理模式構(gòu)建項目的實例展示
- Java設(shè)計模式之代理模式(Proxy模式)介紹
- Java通俗易懂系列設(shè)計模式之代理模式
相關(guān)文章
Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作
這篇文章主要介紹了Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
idea社區(qū)版如何設(shè)置vm?options
這篇文章主要介紹了idea社區(qū)版如何設(shè)置vm?options問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Spring Boot security 默認(rèn)攔截靜態(tài)資源的解決方法
這篇文章主要介紹了Spring Boot security 默認(rèn)攔截靜態(tài)資源,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
Java根據(jù)坐標(biāo)經(jīng)緯度計算兩點距離5種方法及校驗經(jīng)緯度是否在圓/多邊形區(qū)域內(nèi)的算法推薦
在項目開發(fā)過程中需要根據(jù)兩地經(jīng)緯度坐標(biāo)計算兩地間距離,下面這篇文章主要給大家介紹了關(guān)于Java根據(jù)坐標(biāo)經(jīng)緯度計算兩點距離5種方法以及校驗經(jīng)緯度是否在圓/多邊形區(qū)域內(nèi)的算法推薦,需要的朋友可以參考下2023-12-12
Seata集成Mybatis-Plus解決多數(shù)據(jù)源事務(wù)問題
當(dāng)進行業(yè)務(wù)操作時,訂單發(fā)生異常 ,進行了回滾操作,因為在不同的數(shù)據(jù)庫實例中,余額卻扣除成功,此時發(fā)現(xiàn)數(shù)據(jù)不一致問題,本文給大家介紹Seata集成Mybatis-Plus解決多數(shù)據(jù)源事務(wù)問題,感興趣的朋友一起看看吧2023-11-11

