代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。
举一个现实中的例子:
1.顾客
2.客服人员
3.程序员
顾客想向一个公司买一个网站,那么顾客就和客服人员商讨网站细节。客服人员会告诉顾客哪些要求是可以实现,哪些是不能实现的,最后,由客服人员把商讨后的需求告诉程序员,程序员根据需求开始编代码设计网站。
程序人员和客服人员都有设计网站这个功能,只是真正设计网站的是程序人员,客服只是将整理客户的需求告诉程序员。在这个实践当中,客服人员就是代理对象,而程序员是真正的处理对象。
设计代码:因为客服和程序员都有设计网站这个功能,所以是实现同一个接口。
Proxy(代理接口)
public interface Proxy { /** * 设计网站 */ void designWebSite(); }
CustomerService(客服人员)
public class CustomerService implements Proxy { private Programmer programmer = new Programmer(); private int money; @Override public void designWebSite() { System.out.println("我是客服,我会把需求告诉程序员!"); programmer.designWebSite(); } }
Programmer(程序员)
public class Programmer implements Proxy { @Override public void designWebSite() { System.out.println("我是程序员,我才是帮你写网站的人!"); } }
Customer(顾客)
public class Customer { public static void main(String[] args) { CustomerService customerService = new CustomerService(); customerService.designWebSite(); } }调用Customer的main(),打印出:
我是客服,我会把需求告诉程序员!
我是程序员,我才是帮你写网站的人!
到这里,代码只是体现了代理,并没有体现代理的价值,代理的价值就是控制访问。
在哪里控制?在哪里访问就在哪里控制!
所以在客服类中要控制访问,例如,顾客和客服说指向花1W元买这个网站,但是公司的标价是5W,这肯定是不允许的,所以客服要不允许这个动作。修改代码如下:
只需要改动CustomerService(客服人员)和Customer(顾客)
CustomerService(客服人员):
public class CustomerService implements Proxy { private Programmer programmer = new Programmer(); private int money; public CustomerService(int money) { this.money = money; } @Override public void designWebSite() { if(money<50000){ System.out.println("不好意思你的开价太低,我们公司不接受这个交易"); }else{ System.out.println("我是客服,我会把需求告诉程序员!"); programmer.designWebSite(); } } }
在CustomerService中加了个money属性,和带有money属性的构造方法。并且在designWebSite()中去判断money,从而控制是否该请求Programmer。
Customer(顾客)
因为CustomerService的构造方法变了,这里创建CustomerService实例肯定要加参数!
public class Customer { public static void main(String[] args) { CustomerService customerService = new CustomerService(10000); customerService.designWebSite(); } }
运行结果是:
不好意思你的开价太低,我们公司不接受这个交易
这就体现了控制访问的效果。
很多人会有疑问为什么参数要加在构造方法上,不直接加在代理方法上。原因是,如果加在代理方法,用到代理方法的地方都要改,在这里四个类的代理方法都要手动去改,Proxy接口都改了,这是很不友好的。而加在构造方法上,只要改代理对象和调用对象两个。
代理模式的使用场景一般分为以下几种:
第一种:远程代理,就是一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
方便扩展,常用在处理远程访问中,比如分布式访问。
第二种:虚拟代理:是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真是对象。
浏览器的初始化就是代理模式,图片加载的慢, 就先显示一个未打开的图片框,因为图片大小路径存在代理对象中
第三种:安全代理:用来控制真是对象的访问时的权限
第四种:智能指引:是指当调用真是对象时,代理处理另外一些事情。
比如记录调用真实对象的次数。
代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加很多种用途。
如果以上说的有什么不恰当或不准确的描述,请各位指出,一直在学习中。