一、說明
代理模式(百度百科):
- 為其他對象提供一種代理以控制對這個對象的訪問。
- 在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。
二、組成
- 抽象角色(subject):通過接口、抽象類聲明真是角色需要的業(yè)務方法。
- 代理角色(Proxy)代理真實角色操作。
- 真實角色(RealSubject):實現抽象角色,定義真實角色需要的業(yè)務邏輯。
三、類圖

代理模式.png
四、優(yōu)缺點
優(yōu)點:
- 保護目標對象:代理對象可以在客戶端和目標對象之間起到中介作用。
- 高拓展性
缺點:
- 我們得為每一個服務都得創(chuàng)建代理類,工作量太大,不易管理。同時接口一旦發(fā)生改變,代理類也得相應修改。
五、使用場景
- 房產中介、4s店等類似場景
六、注
細心的同學很容易發(fā)現,靜態(tài)代理的類圖和裝飾者模式類圖基本一致。那么他們有什么區(qū)別呢?
- 1.裝飾者模式,顧名思義是用來做裝飾,也就是拓展使用的。
- 2.代理模式,和裝飾者最大的卻別就是設計理念。代理模式是具有一定自主性的,全權代理。代理人可以決定是否來調用被代理人的接口。而裝飾者模式則沒有這種自主性特性。
- 比如4s店可以只在營業(yè)9點-18點才買給你車,其他時間就可以不賣。
七、代碼舉例
(1)subject 抽象接口
/**
* 接口類
*/
public interface ISaleCarInterface {
//賣車
void saleCar();
}
(2) RealSubject 寶馬汽車廠
/**
* 被代理人:寶馬汽車廠
*/
public class BMW implements ISaleCarInterface{
/**
* 汽車廠商自己賣車需要的手續(xù)
*/
@Override
public void saleCar() {
System.out.println("----寶馬廠:收錢----");
System.out.println("----寶馬廠:簽合同----");
System.out.println("----寶馬廠:交車----");
}
}
(3) proxy 代理商:4s店
/**
* 代理人:北京4s店分銷商
*/
public class ProxyBeiJing4S implements ISaleCarInterface {
/**
* 代理寶馬廠賣車
* 代理模式和裝飾模式區(qū)別:
* 這兩種模式實現起來基本一樣,
* 但代理模式設計時是具有一定自主性,代理人在某些情況下可以不調用被代理人,也就是4s店有權不賣給某個人。
* 而裝飾模式是必須要調用被裝飾類的,裝飾模式僅僅是對被裝飾類做一些前置工作而已。
*/
@Override
public void saleCar() {
GregorianCalendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour < 9 || hour > 18) {
System.out.println("====4s店:下班了,明天再來吧!====");
return;
}
System.out.println("====4s店:收費====");
System.out.println("====4s店:收取傭金====");
System.out.println("====4s店:去廠商取車====");
BMW bmw = new BMW();
bmw.saleCar();
System.out.println("====4s店:給客戶推銷保險====");
System.out.println("====4s店:交車!====");
}
}
(4) 客戶端測試類
public class Test {
public static void main(String[] args) {
//靜態(tài)代理模式
ProxyBeiJing4S proxy = new ProxyBeiJing4S();
proxy.saleCar();
}
}
執(zhí)行結果1:
====4s店:收費====
====4s店:收取傭金====
====4s店:去廠商取車====
----寶馬廠:收錢----
----寶馬廠:簽合同----
----寶馬廠:交車----
====4s店:給客戶推銷保險====
====4s店:交車!====
執(zhí)行結果2:
====4s店:下班了,明天再來吧!====