代理模式也稱委托模式,是結構型設計模式之一,在實際應用中使用非常廣泛,因此我們必須掌握這個設計模式。
定義:為一個對象提供一個代理對象,通過這個代理對象控制這個對象的行為。
使用場景:
-
直接訪問或者控制對象的行為困難的時候,可以通過對象的代理對象間接控制對象的行為,為了使用簡單透明,委托對象和代理對象需要實現相同的接口,即同類型,使用方法一樣。
-
可以一定程度上保證對象的安全性。即不必直接將對象暴露給客戶端,而是暴露該對象的代理對象給客戶端,使得將該對象更加安全。但這不是主要的,不然就直接用原型模式了。
和適配器模式的區別:
-
適配器模式是為了一個接口不兼容而導致該接口不能直接使用而用適配器去為該接口適配以到達可以使用的目的,可能需要添加接口的行為(擴展)。
-
代理模式為了使得直接控制一個類的行為困難而使用和該類具有相同行為(實現了相同的接口)的代理對象代替原對象的行為(間接控制),不會添加接口的行為(只是代替而已)。
今年過年小明嫌收到的壓歲錢太少了,生氣了,馬上就要開學了,自己不愿自己去學校報道了,那怎么辦,小明的父母可不能讓小明不報道啊,但又拿小明沒辦法,那只好自己代替小明去給小明報道了唄,于是帶著小明的寒假作業去學校給小明報道了…
以上面的這個例子為例實現代碼模式:
代碼實現:
報道的行為(接口)
~~~
/**
* 開學報道行為(接口)
* @author lt
*
*/
public interface Report {
// 去學校
void goSchool();
// 交學費
void pay();
// 領書本
void getBook();
// 回家
void goHome();
}
~~~
學生(被代理的對象)
~~~
/**
* 學生 (被代理對象)
* @author lt
*
*/
public class Student implements Report{
@Override
public void goSchool() {
System.out.println("開開心心地去學校報道了");
}
@Override
public void pay() {
System.out.println("交了4000學費!");
}
@Override
public void getBook() {
System.out.println("領取了6本書!");
}
@Override
public void goHome() {
System.out.println("總算報道完了,回家了!");
}
}
~~~
家長(代理對象)
~~~
/**
* 家長 (代理對象)
* @author lt
*
*/
public class Parent implements Report{
private Report student; // 持有被代理對象的引用
public Parent(Report student){
this.student = student;
}
@Override
public void goSchool() {
student.goSchool();
}
@Override
public void pay() {
student.pay();
}
@Override
public void getBook() {
student.getBook();
}
@Override
public void goHome() {
student.goHome();
}
}
~~~
測試:(具體的一次報道行為)
~~~
public class Test {
public static void main(String[] args) {
// 小明15歲了,現在在上初中
Report children = new Student();
// 小明今年過年沒收到去年那么多的壓歲錢,不高興了,去年都是自己去報道,今年不去了
Parent parent = new Parent(children);
parent.goSchool();
parent.pay();
parent.getBook();
parent.goHome();
}
}
~~~

通常開學報道的時候都好開心的,因為畢竟剛完年,收到不少壓歲錢,還等著快點去學校花呢。但小明太僑情了,嫌壓歲錢太少了,寧死也不去報道,要小明自己去學校報道太難了,小明的父母只好代替小明去報名了。代替小明去報名也不只有父母才可以哦,還可以是自己的親戚或者其他和關系好的朋友也行。當然,小明的父母也可以代替別人家的孩子報道,比如親戚或者朋友的孩子報道。這說明了,當控制一個對象的行為難的時,可以通過代理對象代替具有一組實現了相同接口的對象的行為,而一個對象也可以有其他的代理對象,前提是兩者實現了相同的接口,即具有相同的行為。
總結:
代理模式的例子無論是在生活中還是在代碼世界里都很常見,使用廣泛,具有解決某些需求的優點,同時也具有設計模式的通病,那就是類的增加。掌握設計模式關鍵在于理解,而不是死記模板,當我在寫代碼的時候在某些特定場合可以自然而然地將我們的設計模式融入應用到我們的程序中,使得我們的程序結構更加清晰,靈活性高,易于擴展等等。