代理模式
在代理模式中,有两个对象参与处理同一请求,接收的请求由代理对象委托给真实对象处理。代理对象在应用中与目标对象之间起到一个中介桥梁的作用
特点
1.代理者和被代理者一般拥有相同的接口或者抽象类
2.在代理对象中,有被代理对象的引用
设计原则:
1.延迟加载,提高系统效率
2.单一职责原则
代理模式使用代理对象将真实对象分离开,可以在代理对象中做一些权限判断,一些逻辑处理。具体动作执行放在真实对象中执行,如此,将代理对象和真实对象的功能职责单一化,分离了不同处理行为,降低了功能模块这几件的耦合度。也方便后期维护,在代理模式中,代理对象与真实对象实现了相同的接口,是面向抽象的编程,也符合设计模式的依赖倒置原则,即依赖抽象,而不依赖与具体实现类(此处代理类,被代理的引用是引用所实现的接口,而不是引用具体的被代理实现类)
使用场合:
1.远程代理:为一个对象在不同的地址空间提供局部代理(aidl就是远程代理)
2.虚拟代理:若一个对象的创建非常耗时,可通过代理对象去调用,在真实对象创建前,范围一个假的调用,等真实对戏那个创建号了。再返回一个真实对象的相应方法调用
3.保护代理:控制对原始对象的访问
4.智能指引
动态代理
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic
Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
Demo
1.实现类接口
public interface IuserManager {
public String test(String userId);
public String test1(String userId,String userName);
}
2.具体实现类public class UserManagerImplimplements IuserManager {
@Override
public String test(String userId) {
System.out.println("UserManagerImpl--》test-->>" + userId);
return"张三";
}
@Override
public String test1(String userId, String userName) {
// TODO Auto-generated method stub
returnnull;
}
}
3.动态代理类
//动态代理,都必须实现 InvocationHandler接口
public class BusinessHandlerimplements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject) {
this.targetObject = targetObject;
// Proxy.newProxyInstance三个参数
// 第一个参数定义代理类型的加载者
// 被代理对象的实现的接口列表
// 实现invocationHandler的对象
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("start-->" + method.getName());
for (int i = 0; i < args.length; i++) {
System.out.println("args-->"+args[i]);
}
Object ret = null;
try {
// 调用目标方法 targetObject method所在的类args为method的参数
ret = method.invoke(targetObject, args);
System.out.println("success-->" + method.getName());
} catch (Exception ex) {
}
// TODO Auto-generated method stub
return ret;
}
}
4.测试BusinessHandler businessHandler = new BusinessHandler();
IuserManager usermanage = (IuserManager) businessHandler.newProxyInstance(new UserManagerImpl());
String name = usermanage.test("001");
System.out.println("Client.main() --- " + name);
测试结果
start-->test
args-->001
UserManagerImpl--》test-->>001
success-->test
Client.main() --- 张三