1.代理模式的概念
為其他對象提供一種代理,以控制對這個對象的訪問。
2.代理模式的結(jié)構(gòu)
Subject類:定義了RealSubject和Proxy的公共接口,這樣就在任何使用RealSubject的地方都可以使用Proxy
RealSubject類:定義Proxy所代表的真實實體
Proxy類:保存一個引用使得代理可以訪問實體,并提供一個與Subject的接口相同的接口,這樣代理就可以用來代替實體。
3.代理模式的基本代碼實現(xiàn)
Subject類:
package com.jxs.proxy;
/**
* Created by jiangxs on 2018/5/3.
*
* Subject類,定義了RealSubject和Proxy的公共接口
*/
public abstract class Subject {
public abstract void request();
}
RealSubject類:
package com.jxs.proxy;
/**
* Created by jiangxs on 2018/5/3.
*
* RealSubject類,定義Proxy所代表的真實實體
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("真實的請求");
}
}
Proxy類:
package com.jxs.proxy;
/**
* Created by jiangxs on 2018/5/3.
*
* Proxy類,保存一個引用,使得代理可以訪問實體
*/
public class Proxy extends Subject {
RealSubject realSubject;
@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request();
}
}
客戶端代碼:
package com.jxs.proxy;
/**
* Created by jiangxs on 2018/5/3.
*/
public class ProxyClient {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.request();
}
}
運行結(jié)果:
真實的請求
Process finished with exit code 0
4.代理模式的應(yīng)用
以《大話設(shè)計模式》中卓賈易讓戴勵替他送禮物給嬌嬌,在這個例子當(dāng)中戴勵就起到了一個代理的作用,其中的GiveGift接口就相當(dāng)于Subject,作為Persuit類和ProxyPeople類的公共接口,Persuit類就相當(dāng)于RealSubject表示真實實體,ProxyPeople類就相當(dāng)于Proxy類表示代理類。
卓賈易讓戴勵替他送禮物給嬌嬌代碼示例:
SchoolGirl類:
package com.jxs.proxyExample;
/**
* Created by jiangxs on 2018/5/3.
*/
public class SchoolGirl {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
GiveGift接口(Subject):
package com.jxs.proxyExample;
/**
* Created by jiangxs on 2018/5/3.
*
* 定義了Persuit和ProxyPeople的公共接口
*/
public interface GiveGift {
void giveDolls();
void giveFlowers();
void giveChocolate();
}
Persuit類(RealSubject):
package com.jxs.proxyExample;
/**
* Created by jiangxs on 2018/5/3.
*
* 相當(dāng)于代理模式中的RealSubject
*/
public class Persuit implements GiveGift {
private SchoolGirl mm;
public Persuit() {}
public Persuit(SchoolGirl mm) {
this.mm = mm;
}
@Override
public void giveDolls() {
System.out.println("送"+mm.getName()+"洋娃娃");
}
@Override
public void giveFlowers() {
System.out.println("送"+mm.getName()+"鮮花");
}
@Override
public void giveChocolate() {
System.out.println("送"+mm.getName()+"巧克力");
}
}
ProxyPeople類(Proxy):
package com.jxs.proxyExample;
/**
* Created by jiangxs on 2018/5/3.
*/
public class ProxyPeople implements GiveGift {
private Persuit gg;
public ProxyPeople() {}
public ProxyPeople(SchoolGirl mm) {
gg = new Persuit(mm);
}
@Override
public void giveDolls() {
gg.giveDolls();
}
@Override
public void giveFlowers() {
gg.giveFlowers();
}
@Override
public void giveChocolate() {
gg.giveChocolate();
}
}
客戶端代碼:
package com.jxs.proxyExample;
/**
* Created by jiangxs on 2018/5/3.
*/
public class Client {
public static void main(String[] args) {
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.setName("嬌嬌");
ProxyPeople daili = new ProxyPeople(jiaojiao);
daili.giveChocolate();
daili.giveDolls();
daili.giveFlowers();
}
}
運行結(jié)果:
送嬌嬌巧克力
送嬌嬌洋娃娃
送嬌嬌鮮花
Process finished with exit code 0
5.代理模式總結(jié)
代理模式適用場合:
遠(yuǎn)程代理:遠(yuǎn)程代理也就是為一個對象在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在于不同地址空間的事實。比如引用WebService,此時就會在項目中生成一個WebReference的文件夾和一些文件,這些就是代理。
虛擬代理:所謂虛擬代理是根據(jù)需要創(chuàng)建開銷很大的對象,通過它來存放實例化需要很長時間的真實對象,這樣就可以達(dá)到性能的最優(yōu)化。
安全代理:用來控制真實對象訪問時的權(quán)限。一般用于對象應(yīng)該有不同的訪問權(quán)限的時候。
智能指引 :是指當(dāng)調(diào)用真實的對象時,代理處理另外一些事。如計算真實對象的引用次數(shù),這樣當(dāng)該對象沒有引用是,可以自動釋放它。
注:以上代碼均可在github上進(jìn)行下載:https://github.com/xsongj/designPattern
參考:《大話設(shè)計模式》