代理模式

代理模式

  代理模式(Proxy),为其他对象提供一种代理以控制这个对象的访问。

代理模式结构图

2.7.1 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//追求者类
public class Pursuit {
SchoolGirl mm;

public Pursuit(SchoolGirl mm) {
this.mm = mm;
}

public void giveDolls(){
System.out.println(mm.getName() + "送你洋娃娃");
}

public void giveFlowers(){
System.out.println(mm.getName() + "送你鲜花");
}

public void giveChocolate(){
System.out.println(mm.getName() + "送你巧克力");
}
}

//被追求者类
public class SchoolGirl {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

public class Test {
public static void main(String[] args) {
//追求者调用被追求者,增送各种礼物
System.out.println("--------------追求者调用被追求者,增送各种礼物");
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.setName("李娇娇");

Pursuit zhuojiayi = new Pursuit(jiaojiao);
zhuojiayi.giveDolls();
zhuojiayi.giveFlowers();
zhuojiayi.giveChocolate();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    public static void main(String[] args) {
//增加代理人
//
System.out.println("--------------增加代理人");
PursuitImpl zhuojiayiNew = new PursuitImpl(jiaojiao);
Proxy daili = new Proxy(zhuojiayiNew);
daili.giveDolls();
daili.giveFlowers();
daili.giveChocolate();
}

//代理接口
public interface IGiveGift {
void giveDolls();
void giveFlowers();
void giveChocolate();
}

public class Proxy implements IGiveGift {
PursuitImpl gg;

public Proxy(PursuitImpl gg) {
this.gg = gg;
}

public void giveDolls(){
gg.giveDolls();
}

public void giveFlowers(){
gg.giveFlowers();
}

public void giveChocolate(){
gg.giveChocolate();
}
}

public class PursuitImpl implements IGiveGift {
SchoolGirl mm;

public PursuitImpl(SchoolGirl mm) {
this.mm = mm;
}

public void giveDolls(){
System.out.println(mm.getName() + "送你洋娃娃");
}

public void giveFlowers(){
System.out.println(mm.getName() + "送你鲜花");
}

public void giveChocolate(){
System.out.println(mm.getName() + "送你巧克力");
}
}

2.7.2 代码结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//定义了RealSubject和Proxy的共用接口,这样就可以在使用RealSubject的地方使用Proxy
public abstract class Subject {
public abstract void request();
}

//定义Proxy所代表的真实实体
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("真实的请求");
}
}

//保存一个引用使得代理可以访问实体,并提供一个与Subject接口相同的接口,使代理可代替实体
public class Proxy extends Subject {
RealSubject realSubject;

@Override
public void request() {
if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();
}
}

public class Main {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.request();
}
}

  代理模式

代理模式的应用场景:

  • 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实,如WebService通过代理来解决远程访问问题。
  • 虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象,以达到性能的优化,比如HTML文件中较大的图片,需要一个个的下载,未打开的图片框就是用虚拟代理代替了真实的图片,此时代理存储了真实图片的路径和尺寸。
  • 安全代理,用来控制真实对象访问时的权限,一般用于对象应该有不同的访问权限的时候。
  • 智能指引,是指当调用真实的对象时,代理处理另外一些事。比如计算真实对象的引用次数,当对象没有引用时就可以自动释放它;或是当第一次引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理。

参考:

🔗 《设计模式:可复用面向对象软件的基础》

🔗 《大话设计模式》