简介
代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。所谓的代理者是指一个类别可以作为其它东西的接口。
优点:可以在目标对象原有的基础上,增加额外的功能。
编程思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式。
组成
抽象角色
通过接口或抽象类声明真实角色实现的业务方法。
代理角色
(代理者)实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色
(委派者)实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
代码演示
抽象角色
通过接口或抽象类声明真实角色实现的业务方法。
抽象角色一般都是接口或抽象类。这里以结婚这件事为例,作为抽象角色。
//接口Marry(结婚),抽象角色
interface Marry{
void HappyMarry();
}
代理角色
(代理者)实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
这里婚庆公司作为代理角色。
- 实现抽象角色
--
实现接口Marry - 是真实角色的代理
--
构造方法中将Marry对象作为参数传递进来 - 通过真实角色的业务逻辑方法来实现抽象方法
--
代理角色实现的抽象方法HappyMarry只是调用真实角色所实现的抽象方法HappyMarry - 并可以附加自己的操作
--
在调用抽象方法HappyMarry时,可以通过方法weddingStart。在weddingStart中可以添加一些自定义操作,例如:before、after
//婚庆公司,待你办理结婚的一些琐事。代理者,代理角色
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作为真实角色,需要结婚。
//要结婚的人,委派者,真实角色
class pete implements Marry{
@Override
public void HappyMarry() {
System.out.printf("pete要结婚了,开心。。。");
}
}
测试类:
下边的测试类中,真实角色(委派者)除了pete之外还有Lily。
调用方法weddingStart来调用抽象方法HappyMarry从而调用真实角色(委派者)的业务逻辑方法–具体是怎么结婚的
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();
}
}
运行结果:
布置婚房、办婚礼...
pete要结婚了,开心。。。
收拾婚礼现场、收尾款...
布置婚房、办婚礼...
lily要结婚了,开心。。。
收拾婚礼现场、收尾款...
Process finished with exit code 0
总结
优点:可以在目标对象原有的基础上,增加额外的功能。
编程思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式。
代理角色:可以做很多真实角色做不了的事情(扩展)
真实角色:可以专注于做自己的事情
例子:多线程中的Thread类与Runnable接口。传送门
- 抽象角色 – Runnable接口
- 代理角色 – Thread类(通过查看源码可以发现Thread类实现了Runnable接口)
- 真实角色 – 实现Runnable接口的子类
- 开启线程:
new Thread(实现Runnable接口的子类实例).start();
完整代码:
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");
}
}
原文链接:静态代理模式