一、含义
为另一个对象提供一个替身或占位符以访问这个对象。个人理解就是,在调用真正的对象之间,通过调用这个对象的代理,可新增新的功能。
二、要点
1.代理模式是为一个对象提供一个代表,以便控制客户对向真实对象的访问。
2.代理在结构上类似装饰者,但是目的不同;装饰者模式是为对象添加新的行为,代理则是控制访问。
三、实战分析代理模式
首先来看一下代理模式的类图:
在这里我们直接分析java中常见的两种代理模式,静态代理和动态代理。
1.静态代理:就是由我们自己创建代理类。
比如对于我们这种没有房子的人来说,租房就是一个头等大事,每个月的工资都交给了房东,满满的心酸了,不谈!有的时候比较着急找房子,为了能快速找到房子,这个时候我们就要找中介了,中介其实就是一个代理,而房东就是真正的对象。
首先我们来创建一个接口,提供一个出租房屋的方法。
/**
* 房东接口
*/
public interface Landlord {
/**
* 出租房子的方法
*/
void RentHouse();
}
然后就是一个房东的具体实现类:
/**
* 具体的一个房东
*/
public class DefaultLandlord implements Landlord {
/**
* 出租房子的实现
*/
@Override
public void RentHouse() {
System.out.println("我的房子出租2000,赶紧来租,不然就没有咯");
}
}
然后就需要一个代理了,当然代理手中有一堆房子供你选择,但代理当然不能白给你提供这么多房子,人家需要适当的收取一些服务费了,代理代码实现如下:
public class ProxyLandlord implements Landlord {
/** 接收出租房屋的房东 */
private Landlord landlord;
public ProxyLandlord(Landlord landlord) {
//实例真正的房东
this.landlord = landlord;
}
/**
* 出租房屋的方法
*/
@Override
public void RentHouse() {
System.out.println("给你提供房源,先交个500押金!");
//真正的对象
landlord.RentHouse();
}
}
因为中介是没有房子的,房子的拥有者是房东,需要最后租房还是要从房东手上来租房,最后编写我们的测试类:
public static void main(String[] args) {
//真正的房东——真是对象
Landlord landlord = new DefaultLandlord();
//中介——代理
Landlord proxyLord = new ProxyLandlord(landlord);
//找中介租房子
proxyLord.RentHouse();
}
测试结果如下:
给你提供房源,先交个500押金!
我的房子出租2000,赶紧来租,不然就没有咯
2.动态代理:就是程序帮我们动态生成一个代理,不需要我们手动去生成。
就比如现在的很多大的中介,当我们找房子的时候,中介会动态的给我们分配一个业务员,来给我们提供服务,并不需要我们自己去找业务员来帮助我们。代码实现如下:
之前的接口和房东类不变,只需修改代理类的实现:
public class DynamicProxyLord {
/**
* 用来接收房东对象
*/
private Object landlord;
public DynamicProxyLord(Landlord landlord) {
this.landlord = landlord;
}
/**
* 动态创建代理
* @return
*/
public Object getProxyInstance() {
return Proxy.newProxyInstance(landlord.getClass().getClassLoader(),
landlord.getClass().getInterfaces(),(proxy,method,args) ->{
System.out.println("帮你省了找业务员,先叫个定金600!");
Object object = method.invoke(landlord,args);
return object;
});
}
}
最后来编写一个测试类:
public static void main(String[] args) {
Landlord landlord = new DefaultLandlord();
Landlord proxyLord = (Landlord) new DynamicProxyLord(landlord).getProxyInstance();
proxyLord.RentHouse();
}
测试结果如下:
帮你省了找业务员,先叫个定金600!
我的房子出租2000,赶紧来租,不然就没有咯