0%

静态代理模式

简介

代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。所谓的代理者是指一个类别可以作为其它东西的接口。

优点:可以在目标对象原有的基础上,增加额外的功能。
编程思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式。

组成

抽象角色

通过接口或抽象类声明真实角色实现的业务方法。

代理角色

(代理者)实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

真实角色

(委派者)实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

以上简介摘自百度百科,更详细介绍见菜鸟教程

代码演示

抽象角色

通过接口或抽象类声明真实角色实现的业务方法。

抽象角色一般都是接口或抽象类。这里以结婚这件事为例,作为抽象角色。

1
2
3
4
//接口Marry(结婚),抽象角色
interface Marry{
void HappyMarry();
}

代理角色

(代理者)实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

这里婚庆公司作为代理角色。

  • 实现抽象角色--实现接口Marry
  • 是真实角色的代理--构造方法中将Marry对象作为参数传递进来
  • 通过真实角色的业务逻辑方法来实现抽象方法--代理角色实现的抽象方法HappyMarry只是调用真实角色所实现的抽象方法HappyMarry
  • 并可以附加自己的操作--在调用抽象方法HappyMarry时,可以通过方法weddingStart。在weddingStart中可以添加一些自定义操作,例如:before、after
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
//婚庆公司,待你办理结婚的一些琐事。代理者,代理角色
class WeddingCompany implements Marry{

//要结婚的人,委派者
private Marry target;
public WeddingCompany(Marry target){
this.target = target;
}
@Override
public void HappyMarry() {//接口Marry中定义的方法
target.HappyMarry();
}

public void weddingStart(){// 婚礼开始

before();//结婚前的准备工作
HappyMarry();
after();//结婚后的收尾工作

}

public void before(){//结婚前的准备工作
System.out.printf("布置婚房、办婚礼...\n");
}
public void after(){//结婚后的收尾工作
System.out.printf("\n收拾婚礼现场、收尾款...\n\n");
}
}

真实角色

实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

这里以一个虚拟人物pete作为真实角色,需要结婚。

1
2
3
4
5
6
7
//要结婚的人,委派者,真实角色
class pete implements Marry{
@Override
public void HappyMarry() {
System.out.printf("pete要结婚了,开心。。。");
}
}

测试类

下边的测试类中,真实角色(委派者)除了pete之外还有Lily。

调用方法weddingStart来调用抽象方法HappyMarry从而调用真实角色(委派者)的业务逻辑方法–具体是怎么结婚的

1
2
3
4
5
6
7
8
9
public class StacticProxy {
public static void main(String[] args) {
WeddingCompany wc = new WeddingCompany(new pete());
wc.weddingStart();

//或(使用lambda表达式)
new WeddingCompany(()-> System.out.printf("lily要结婚了,开心。。。")).weddingStart();
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
布置婚房、办婚礼...
pete要结婚了,开心。。。
收拾婚礼现场、收尾款...

布置婚房、办婚礼...
lily要结婚了,开心。。。
收拾婚礼现场、收尾款...


Process finished with exit code 0

总结

优点:可以在目标对象原有的基础上,增加额外的功能。
编程思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式。
代理角色:可以做很多真实角色做不了的事情(扩展)
真实角色:可以专注于做自己的事情

例子:多线程中的Thread类与Runnable接口。传送门

  • 抽象角色 – Runnable接口
  • 代理角色 – Thread类(通过查看源码可以发现Thread类实现了Runnable接口)
  • 真实角色 – 实现Runnable接口的子类
  • 开启线程:new Thread(实现Runnable接口的子类实例).start();

完整代码

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
public class StacticProxy {
public static void main(String[] args) {
WeddingCompany wc = new WeddingCompany(new pete());
wc.weddingStart();

//或(使用lambda表达式)
new WeddingCompany(()-> System.out.printf("lily要结婚了,开心。。。")).weddingStart();
}

}

//接口Marry(结婚),抽象角色
interface Marry{
void HappyMarry();
}

//要结婚的人,委派者,真实角色
class pete implements Marry{
@Override
public void HappyMarry() {
System.out.printf("pete要结婚了,开心。。。");
}
}

//婚庆公司,待你办理结婚的一些琐事。代理者,代理角色
class WeddingCompany implements Marry{

//要结婚的人,委派者
private Marry target;
public WeddingCompany(Marry target){
this.target = target;
}
@Override
public void HappyMarry() {//接口Marry中定义的方法
target.HappyMarry();
}

public void weddingStart(){// 婚礼开始

before();//结婚前的准备工作
HappyMarry();
after();//结婚后的收尾工作

}

public void before(){//结婚前的准备工作
System.out.printf("布置婚房、办婚礼...\n");
}
public void after(){//结婚后的收尾工作
System.out.printf("\n收拾婚礼现场、收尾款...\n\n");
}
}

学习自B站遇见狂神说

若图片不能正常显示,请在浏览器中打开

欢迎关注我的其它发布渠道