代理模式学习
代理模式
代理模式是结构型模式,相当于给一个对象生成一个代理对象,我们去访问的时候直接面对的是代理对象。在平时的生活中也有类似的例子,比如房产中介,我们在租房的时候面对的不是真正的房东而是中介,这个中介就相当于房东的代理对象。代理对象可以对原对象的功能进行增强。下面通过一张图来展示下代理模式。
在上图中,我们可以看到代理类和被代理类都需要继承同一个接口,然后代理类又继承了被代理类,这样就可以对被代理类进行功能增强。然后我们用户访问的是代理类。
代理类型的分类:
- 静态代理
- 动态代理
静态代理
静态代理:相当于提前实现好代理类,在需要的时候直接创建实例即可。静态代理存在一些局限,比如一些被代理类需要相同的功能增强逻辑,静态代理就需要一个个去实现这些类的代理类,非常的麻烦,编码量大,同时也不易管理。
静态代理代码实现
场景描述:用户去租房,租房找的都是中介而并非房东
- 实现租房接口
//租房接口
public interface Rent {
void rentHouse();
}
- 房东类的实现(也就是被代理类),需要实现接口
//房东类实现了租房的接口
public class Host implements Rent {
@Override
public void rentHouse() {
System.out.println("我是房东,我要出租房子");
}
}
- 中介类的实现(也就是代理类),需要实现接口
//中介类,同样实现了租房接口,并且需要加入房东类,调用房东类中的功能
public class RentProxy implements Rent {
private Host host;
public RentProxy(Host host) {
this.host = host;
}
@Override
public void rentHouse() {
System.out.println("我是中介,带着客户去看房子"); host.rentHouse();
}
}
- 测试代码
public class ProxyTest {
public static void main(String[] args) {
//调用中介的租房方法
RentProxy proxy = new RentProxy(new Host());
proxy.rentHouse();
}
}
动态代理
动态代理,相对于静态代理来说就是代理类是动态生成的而不是提前编码好。动态代理,减少了编码量以及方便管理。这里动态代理的实现是基于接口的实现。动态代理的有两种常见的实现:
- Jdk动态代理:基于接口的实现。
- cglib动态代理:基于类的实现。
下面的代码实现是基于接口的实现,也就是jdk动态代理
动态代理代码实现
- 同静态代理第一步:实现租房接口
- 同静态代理第二步:实现房东类
- 实现代理handler,这里没有实现代理类,区别于静态代理
//实现代理handler
public class RentProxyHandler implements InvocationHandler {
private Object rent;
public RentProxyHandler(Object rent) {
this.rent = rent;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
//功能增强
System.out.println("中介带着客户去看房子");
//调用被代理类中的方法
method.invoke(rent,args);
return null;
}
}
- 测试代码
public class ProxyTest {
public static void main(String[] args) {
//创建需要被代理的对象,这里就是房东
Host host = new Host();
//创建代理handller,然后将需要被代理的对象传入到handller中
RentProxyHandler proxyHandler = new RentProxyHandler(host);
//这里用于动态的生成代理对象,也就是相当于我们之前写RentProxy,不过这里我们是自动生成的
Rent rentProxy = (Rent) Proxy.newProxyInstance(host.getClass().getClassLoader(),
host.getClass().getInterfaces(), proxyHandler);
rentProxy.rentHouse();
}
}
有道无术,术尚可求。
有术无道,止于术。