1.代理模式的概念
為其他對(duì)象提供一種代理记舆,以控制對(duì)這個(gè)對(duì)象的訪問拨扶。
2.代理模式的結(jié)構(gòu)
Subject類:定義了RealSubject和Proxy的公共接口凳鬓,這樣就在任何使用RealSubject的地方都可以使用Proxy
RealSubject類:定義Proxy所代表的真實(shí)實(shí)體
Proxy類:保存一個(gè)引用使得代理可以訪問實(shí)體,并提供一個(gè)與Subject的接口相同的接口患民,這樣代理就可以用來代替實(shí)體缩举。
3.代理模式的基本代碼實(shí)現(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所代表的真實(shí)實(shí)體
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("真實(shí)的請(qǐng)求");
}
}
Proxy類:
package com.jxs.proxy;
/**
* Created by jiangxs on 2018/5/3.
*
* Proxy類仅孩,保存一個(gè)引用,使得代理可以訪問實(shí)體
*/
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();
}
}
運(yùn)行結(jié)果:
真實(shí)的請(qǐng)求
Process finished with exit code 0
4.代理模式的應(yīng)用
以《大話設(shè)計(jì)模式》中卓賈易讓戴勵(lì)替他送禮物給嬌嬌印蓖,在這個(gè)例子當(dāng)中戴勵(lì)就起到了一個(gè)代理的作用辽慕,其中的GiveGift接口就相當(dāng)于Subject,作為Persuit類和ProxyPeople類的公共接口赦肃,Persuit類就相當(dāng)于RealSubject表示真實(shí)實(shí)體溅蛉,ProxyPeople類就相當(dāng)于Proxy類表示代理類。
卓賈易讓戴勵(lì)替他送禮物給嬌嬌代碼示例:
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();
}
}
運(yùn)行結(jié)果:
送嬌嬌巧克力
送嬌嬌洋娃娃
送嬌嬌鮮花
Process finished with exit code 0
5.代理模式總結(jié)
代理模式適用場(chǎng)合:
遠(yuǎn)程代理:遠(yuǎn)程代理也就是為一個(gè)對(duì)象在不同的地址空間提供局部代表他宛。這樣可以隱藏一個(gè)對(duì)象存在于不同地址空間的事實(shí)温艇。比如引用WebService,此時(shí)就會(huì)在項(xiàng)目中生成一個(gè)WebReference的文件夾和一些文件堕汞,這些就是代理勺爱。
虛擬代理:所謂虛擬代理是根據(jù)需要?jiǎng)?chuàng)建開銷很大的對(duì)象,通過它來存放實(shí)例化需要很長時(shí)間的真實(shí)對(duì)象讯检,這樣就可以達(dá)到性能的最優(yōu)化琐鲁。
安全代理:用來控制真實(shí)對(duì)象訪問時(shí)的權(quán)限。一般用于對(duì)象應(yīng)該有不同的訪問權(quán)限的時(shí)候人灼。
智能指引 :是指當(dāng)調(diào)用真實(shí)的對(duì)象時(shí)围段,代理處理另外一些事。如計(jì)算真實(shí)對(duì)象的引用次數(shù)投放,這樣當(dāng)該對(duì)象沒有引用是奈泪,可以自動(dòng)釋放它。
注:以上代碼均可在github上進(jìn)行下載:https://github.com/xsongj/designPattern
參考:《大話設(shè)計(jì)模式》