到网上找这个模式的例子,不知为何,突然觉得这个和之前写的装饰器模式特别像
感觉都做了一件:方法增强!
代理模式:为其他对象提供一种代理以控制对这个对象的访问.
这里要理解【控制】为何物,又是如何做到控制的。
代理模式有以下角色:
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
Example:用代理实现一个场景,十二运召开了,一票难求,不得已,有许多代理售票点。
用代理模式实现【这个例子合适吗 ?】
1. 抽象角色
/**
* 抽象角色 : 售票窗接口
*
* @author king
*
*/
public interface IWicket {
//主要功能是售票
void sell();
}
2.真实角色
/**
* 真实角色:售票窗
*
* @author king
*/
public class Wicket implements IWicket{
@Override
public void sell() {
System.out.println("给一张十二运的票....");
}
}
3.代理角色
/**
*
* 代理角色
*
* @author king
*
*/
public class ProxyWicket implements IWicket {
private IWicket wicket;
/**
* 代理类调用被代理类的方法
*/
@Override
public void sell() {
if(null == wicket){
wicket = new Wicket();//被代理的对象
}
System.out.println("HY来到代理点买十二运人的票");
wicket.sell();
}
}
4. 运行类
public class Main {
public static void main(String[] args) {
//没被代理之前
IWicket wicket = new Wicket();
System.out.println("去窗口买票.....");
wicket.sell();
System.out.println("----------------------");
//被代理之后
System.out.println("去代理点买票.....");
IWicket proxywicket = new ProxyWicket();
proxywicket.sell();
}
}
运行结果:
去窗口买票.....
给一张十二运的票....
----------------------
去代理点买票.....
HY来到代理点买十二运人的票
给一张十二运的票....
想到了什么,java的动态代理是不是?
JDK动态代理
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法
(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
example:先实现一个登陆校验功能,但是当它被代理的时候,在校验的前后要插入日志
1.业务逻辑接口
/**
* 业务逻辑接口
*
* @author king
*
*/
public interface ILoginService {
//对应的业务方法
void login();
}
2. 实现类
/**
* 实现类
*
* @author king
*
*/
public class LoginService implements ILoginService{
//验证用户名,实现登陆功能
@Override
public void login() {
System.out.println("校验用户名和密码...");
}
}
3..日志方法
/**
*
* 日志类
*
* @author king
*
*/
public class LogUtil {
//方法被执行之前调用
public static void before(String method){
System.out.println("before call: "+ method);
}
//方法被执行后调用
public static void after(String method){
System.out.println("after call: "+method);
}
}
4.动态代理类
/**
* 动态代理,实现日志插入功能
*
* @author king
*
*/
public class ProxyService implements InvocationHandler {
private Object target;//定义一个代理的目标类
public ProxyService(Object target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//方法执行前
LogUtil.before(target.getClass().getName()+"."+method.getName());
Object obj = method.invoke(target, args);
//方法执行后
LogUtil.before(target.getClass().getName()+"."+method.getName());
return obj;
}
}
5. 运行类:
public class Main {
public static void main(String[] args) {
ILoginService target = new LoginService();
ProxyService handler = new ProxyService(target);
ILoginService proxy = (ILoginService)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), handler);
proxy.login();
}
}
运行结果:
before call: designpattern.jdk.proxy.LoginService.login
校验用户名和密码...
before call: designpattern.jdk.proxy.LoginService.login
本人菜鸟HY大神的一阳神指
参考文档 <http://blog.csdn.net/jianghuxiaoxiami/article/details/3403924> ,此处致谢