一、简介
在我们实际生活中,经常会遇到代理模式,比如,上大学时,有时候不愿意去上课,但是为了应付老师,就让同学代签到。再比如,VPN也是一个很好的例子。通过浏览器配置代理地址,让你能访问到facebook, youtube, twitter等等被GW墙掉的网站。
所谓的代理,就是通过引用一个新的对象来实现对真实对象的操作或者将新的对象当做真实对象的一个替身,这种实现的机制就是代理模式,通过引用代理对象来访问真实对象就是代理模式的设计动机。
二、模式定义
代理模式就是给一个对象提供一个代理,并由代理对象控制原对象的引用。
在代理模式中,“第三者”代理主要 是起到一个中介的作用,它连接客户端和目标对象
三、代理模式的UML结构图
代理模式存在如下三个角色:
Subject:抽象角色。声明真实对象和代理对象的共同接口。
Proxy:代理角色。代理对象与真实对象实现相同的接口,所以它能够在任何时候都能代理真实的对象。代理角色内部包含对真实对象的引用,所以它可以操作真实对象,同时也可以附加其他的操作,相当于对真实
对象进行封装。
RealSubject:真实角色。它代表着真实对象,是我们最终要引用的对象。
四、模式的实现
以春节买票来作为例子吧。12306 ticket helper是个不错的插件,它其实是一个代理角色。我们把必须要的信心给它之后,它会一直刷票,直到有票为止。
定义一个买票的接口:
package com.desmond.test.proxy;
/**
* Ticket.java
* @author Presley
* @date 2014年2月23日
*/
public interface Ticket {
long buyTicket(String IDNumber);
}
真实的角色:
package com.desmond.test.proxy;
/**
* TicketSystem.java
* @author Presley
* @date 2014年2月23日
*/
public class TicketSystem implements Ticket {
@Override
public long buyTicket(String IDNumber) {
int randomInteger = (int)(Math.random()*10) + 1;
boolean isGrabed = (randomInteger) % 3 == 0;
if(isGrabed) {
System.out.println("information from 12306.cn: Person who own the ID number "
+ IDNumber + " had got the ticket, order Number: " + 123456);
return 123456;
} else {
System.out.println("information from 12306.cn: Person who own the ID number "
+ IDNumber + " are failed to got a ticket. ");
return 0;
}
}
}
代理角色:package com.desmond.test.proxy;
package com.desmond.test.proxy;
/**
* TicketHelper.java
* @author Presley
* @date 2014年2月23日
*/
public class TicketHelper implements Ticket{
private Ticket ticket;
public TicketHelper() {
this.ticket = new TicketSystem();
}
@Override
public long buyTicket(String IDNumber) {
long orderNum = 0;
while((orderNum = ticket.buyTicket(IDNumber)) == 0) {
try {
Thread.currentThread().sleep(1000);
System.out.println("buy a ticket failed, let try it again...");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return orderNum;
}
}
客户端:
package com.desmond.test.proxy;
/**
* Customer.java
* @author Presley
* @date 2014年2月23日
*/
public class Customer {
public static void main(String[] args) {
Ticket proxy = new TicketHelper();
long orderNumber = proxy.buyTicket("47823418890908124x");
}
}
运行结果:
information from 12306.cn: Person who own the ID number 47823418890908124x are failed to got a ticket.
buy a ticket failed, let's try it again...
information from 12306.cn: Person who own the ID number 47823418890908124x are failed to got a ticket.
buy a ticket failed, let's try it again...
information from 12306.cn: Person who own the ID number 47823418890908124x had got the ticket, order Number: 123456
五、模式的优缺点
优点:
1.代理模式能偶协调和调用者和被调用者,在一定程度上降低了系统耦合度
2. 代理对象可以在客户端和目标对象之间起到一个中介作用,可以保护目标对像
3. 减少资源的消耗,可以把比较耗资源的对象代理起来,用以共享,从而减轻开销
缺点:
1. 影响系统性能。由于在客户端与真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
2. 增加代码的复杂度。实现代理模式需要额外的工作,有些代理模式的实现非常复杂
六、适用场景
1. 远程代理:为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实
2. 虚拟代理:通过适用一个小的对象代理一个大的对象。这样可以减少系统的开销
3. 保护代理:可以用来控制对真实对象的访问权限
七、总结
1、代理模式是通过使用引用代理对象来访问真实对象,在这里代理对象充当用于连接客户端和真实对象的中介者。
2、代理模式主要用于远程代理、虚拟代理和保护代理。其中保护代理可以进行访问权限控制。
来自: http://blog.csdn.net/chenssy/article/details/11179815