什么是代理模式
为其他对象提供一种代码以控制对这个对象的访问。
模式角色
抽象角色(MovieStar)
通过接口或抽象类声明真实角色实现的业务方法。
真实角色(BaoQiangStar)
实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
代理角色(AgentProxy)
实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作
UML类图
代理模式代码实现
现实世界中有很多代理场景,比如租房。房东为真实租房角色,中介为房东代理租售业务。明星都有经纪人帮忙协调资源等等。
静态代理实现:编辑代理类代码,实现代理模式;在编译期就生成了代理类。
public interface MovieStar {
public void movie();
}
public class BaoQiangStar implements MovieStar {
@Override
public void movie() {
System.out.println("宝强出演电影.");
}
}
public class AgentProxy implements MovieStar {
private BaoQiangStar baoQiangStar;
public AgentProxy(BaoQiangStar baoQiangStar) {
this.baoQiangStar = baoQiangStar;
}
public void contract() {
System.out.println("宝强出演电影前,经纪人先签合同.");
}
@Override
public void movie() {
contract();
baoQiangStar.movie();
}
}
public class Client {
public static void main(String[] args) {
BaoQiangStar baoQiangStar = new BaoQiangStar();
AgentProxy agentProxy = new AgentProxy(baoQiangStar);
agentProxy.movie();
}
}
动态代理:代理类在程序运行时创建的代理方式被称为动态代理。也就是说,代理类并不需要在Java代码中定义,而是在运行时动态生成的。基于 JDK 实现动态代理,通过jdk提供的工具方法Proxy.newProxyInstance动态构建全新的代理类(继承Proxy类,并持有InvocationHandler接口引用 )字节码文件并实例化对象返回。(jdk动态代理是由java内部的反射机制来实例化代理对象,并代理的调用委托类方法)
抽象角色和真实角色不做修改,代理类角色不再和真实角色一样实现抽象角色而是实现InvocationHandler。
public class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk动态代理.....");
Object o = method.invoke(target, args);
return o;
}
}
public class Client {
public static void main(String[] args) {
BaoQiangStar baoQiangStar = new BaoQiangStar();
InvocationHandler invocationHandler = new DynamicProxyHandler(baoQiangStar);
// 参数1:指定当前目标对象使用的类加载器
// 参数2:指定要被代理类的接口
// 参数3:执行目标对象方法时会触发事件处理方法。
MovieStar movieStar = (MovieStar) Proxy.newProxyInstance(baoQiangStar.getClass().getClassLoader(), baoQiangStar.getClass().getInterfaces(), invocationHandler);
movieStar.movie();
}
}
优点
实现了访问者与访问对象之间的解耦
代理模式在客户端与对象之间起到中介作用,保护了对对象的访问
代理模式可以在访问过程中增加逻辑(aop)
缺点
静态代理重用性不高,一百个明星(真实角色)就要有一百个经纪人(代理)。
网友评论