本文参考:
https://blog.csdn.net/jason0539/article/details/22974405
https://www.cnblogs.com/pony1223/p/5588964.html
https://www.cnblogs.com/jenkinschan/p/6291328.html
一、概述
代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。即为指定的目标对象提供一个代理商,由代理商来完成对目标对象的操作。
生活中常见的例子比如:我们买机票,那么购买平台就是一个代理。我们去中介想要买房子,中介就是代理。
二、结构类图
三、应用实例
下面以人去买车来作为实例讲解如下:
新建一个买车的接口:
public interface Buy_Car
{
public void buy_mycar();
}
新建一个people人类,具有买车的行为,所以实现接口buy_car
public class People implements Buy_Car
{
private int cash;
private String vip;
private String username;
@Override
public void buy_mycar() {
System.out.print(username+"是vip 客户,可以直接购买新车!");
}
public int getCash() {
return cash;
}
public void setCash(int cash) {
this.cash = cash;
}
public String getVip() {
return vip;
}
public void setVip(String vip) {
this.vip = vip;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
people类不能拥有车,必须经过proxy代理类的认证,符合条件之后才可以拥有车辆,新建一个代理,这个代理类来考察当前的people是否有资格进行买车:
public class ProxyClass implements Buy_Car
{
private People people;
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
@Override
public void buy_mycar()
{
if (people.getVip() == "vip")
{
people.buy_mycar();
return;
}
if (people.getCash() >= 50000)
{
System.out.println(people.getUsername() + "买了新车,交易结束!");
} else {
System.out.println(people.getUsername() + "钱不够,不能买车,继续比赛!");
}
}
}
最后创建一个客户端,用来模拟买车的行为:
public class RunClient {
/**
* @param args
*/
public static void main(String[] args) {
People people_1 =new People();
people_1.setCash(60000);
people_1.setUsername("jeck");
People people_2 =new People();
people_2.setCash(40000);
people_2.setUsername("rose");
People people_3 =new People();
people_3.setCash(0);
people_3.setUsername("tom");
people_3.setVip("vip");
ProxyClass proxy_buy = new ProxyClass();
proxy_buy.setPeople(people_1);
proxy_buy.buy_mycar();
proxy_buy.setPeople(people_2);
proxy_buy.buy_mycar();
proxy_buy.setPeople(people_3);
proxy_buy.buy_mycar();
}
}
运行结果如下:
jeck买了新车,交易结束!
rose钱不够,不能买车,继续比赛!
tom是vip 客户,可以直接购买新车!
代理模式主要使用了java的多态,干活的是被代理类,代理类主要是接活,你让我干活,好,我交给幕后的类去干,你满意就成,那怎么知道被代理类能不能干呢?同根就成,大家知根知底,你能做啥,我能做啥都清楚得很,同样一个接口
四、其他代理
1、虚拟代理:可以作为创建开销大的对象的代表,虚拟代理让我们真正需要使用一个对象时才会去创建这个对象。在对象创建前和创建中,虚拟代理扮演真实对象的替身,当对象创建完毕后,虚拟代理会把请求直接委托给真实对象。虚拟代理在手机页面加载中经常可以见到,比如打开页面显示"**正在玩命加载中..."。
2、缓存代理:可以理解成把网络上的静态资源或者不常改变的数据保存在本地,再次访问的这次数据的时候直接从本地读取。应用例子有页面的缓存机制、cdn、app缓存机制等。
3、保护代理:根据角色或者其他机制控制用户对一些资源的访问权限。这常见于一些网站需要登录才能获取更多的内容,struts2和spring的拦截器等。
4、静态代理:可以理解为对象由代理创建,在创建前后做一些事情,比如统计创建了多少对象,但静态代理只能创建一个或固定的几个对象。详见:http://blog.csdn.net/lidatgb/article/details/8941711。
5、动态代理:其用途跟静态代理类型,但可以利用反射机制动态地创建对象,可以减少代理代码的重复,有更好的扩展性。详见:http://blog.csdn.net/lidatgb/article/details/8993131。
6、正向代理:用户可以指定代理服务器转发请求到目标服务器完成,用户知道代理服务器地址和目标服务器地址。常见于翻墙代理服务器。
7、反向代理: 用户访问的目标服务器其实是代理服务器,代理服务器做负载均衡后把请求转发到真正的目标服务器执行。常见于负载均衡服务器。
五、使用场景
由代理的概述中知道,但需要控制对资源或者对象的访问时使用代理模式。从代理的种类中可以进一步看清代理模式的使用场景,无非就是转发远程请求、作为创建开销大对象的替身、在本地保存网络资源、控制一些受保护资源的权限访问、作负载均衡。