java设计模式(4)--代理模式

来源:互联网 发布:大智慧批量导出数据 编辑:程序博客网 时间:2024/04/24 09:10


一、静态代理类:

由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

该模式有以下角色:

(1)抽象角色(Subject):负责声明真实对象和代理对象的共同接口;

(2)代理角色(ProxySubject):内部包含真实对象的引用,负责对真实对象进行再封装以提供特定的服务。

(3)真实角色(RealSubject):被代理的真实对象,负责提供实现的具体服务。


/** * 抽象角色 */public interface Subject {public void say();}/** * 真实角色 * */public class RealSubject implements Subject {    @Override    public void say() {        System.out.println("hello world!");    }}/** * 代理角色 */public class ProxySubject implements Subject{        //真实角色引用    private Subject subject;    public ProxySubject(Subject subject) {        this.subject = subject;    }        @Override    //对真实对象进行再封装,并在真实对象的前后进行切面处理    public void say() {        System.out.println("start saying...");        //相当于回调        subject.say();        System.out.println("stop saying...");        }}/** * 测试类 */@Testpublic void test2(){     Subject s = new RealSubject();     ProxySubject ps = new ProxySubject(s);     ps.say();}

缺点:(1)当我们在抽象对象中增加一个方法时,那么不仅在真实角色中需要进行修改,代理角色中也要进行修改。

(2)每个代理类只能为一个抽象角色服务(如果我们一个代理类实现多个接口,那么一个代理就可以用到所有的接口的方法而非自己接口的方法),这样会产生过多的同功能代理类,而且各代理类除了调用的方法不一样之外,其它代码都一样,代码重复严重。

二、动态代理类

在程序运行时,运用反射机制动态创建而成。

JDK提供了java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类支持动态代理的实现。

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。

/** * 抽象角色(同静态代理) */public interface Subject {public void say();}/** * 真实角色(同静态代理) * */public class RealSubject implements Subject {    @Override    public void say() {        System.out.println("hello world!");    }}/** * 动态代理类 * *///继承自java.lang.reflect.InvocationHandler接口public class DynamicProxy implements InvocationHandler{        //真实对象引用    private Object subject;        public DynamicProxy(Object subject) {        super();        this.subject = subject;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {        System.out.println("welcome ");        Object result = method.invoke(subject, args);        return result;    }}/** * 测试类 */@Testpublic void test4(){       Subject  s = new RealSubject();        DynamicProxy dp = new DynamicProxy(s);        Subject sProxy = (Subject)Proxy.newProxyInstance(s.getClass().getClassLoader(), new Class[]{Subject.class},dp);        sProxy.say();}

缺点:(1)只能代理实现了接口的类,有些类没实现接口的就不能使用JDK代理。

三、应用场合

         (1)不允许直接访问某些类;

         (2)对访问要做特殊处理等


	
				
		
原创粉丝点击