zoukankan      html  css  js  c++  java
  • java实现23种设计模式之代理模式

    看代码:

    package com.ceshi7;
    
    public interface Sourceable {
        public void method();
    }
    package com.ceshi7;
    
    public class Source implements Sourceable{
    
        @Override
        public void method() {
            System.out.println("这是原方法!");
        }
    
    }
    package com.ceshi7;
    
    public class Proxy implements Sourceable{
        private Source source;
        public Proxy(){
            super();
            this.source = new Source();
        }
        @Override
        public void method() {
            before();
            source.method();
            atfer();
        }
        private void atfer() {
            System.out.println("代理之后!");
        }
        private void before() {
            System.out.println("代理之前!");
        }
    }
    package com.ceshi7;
    
    public class ProxyTest {
        public static void main(String[] args) {
            Sourceable source = new Proxy();
            source.method();
        }
    }

    测试结果:

    忽然发现该代理模式和之前的装饰器模式极其相似。

    区别仅在于需要用到的装饰器模式调用时引入了一个对象,而代理模式并没有;

    但是其中思想并不同,装饰器模式只是将引用的类进行装饰,也就是用来扩展;

    而代理模式则是用来代理处理一些相关事物。

    所以修改的话使用代理模式是对代理类进行修改。装饰器模式是对接口的实现进行扩展。

    一个是修改,一个是增加。两者经常结合使用。

    感觉是增加一个装饰类仿佛是增加一个代理类,可以这么理解。

    代理模式的应用场景:
    如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法:
    1、修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则,即闭包原则。
    2、就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
    使用代理模式,可以将功能划分的更加清晰,有助于后期维护。
    即我们需要修改时只要修改代理类就可以了。
     
    以上仅是静态代理,如果是动态代理呢?
    package com.ceshi7;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyTest1 {
        public static void main(String[] args) throws Throwable {
            Source target = new Source();
            //传入目标对象
            //目的:1.根据它实现的接口生成代理对象 2.代理对象调用目标对象方法
            Sourceable sourceable = (Sourceable) getProxy(target);
            sourceable.method();
        }
        
        private static Object getProxy(final Object target) throws Exception{
            //参数1:随便找个类加载器给它, 参数2:目标对象实现的接口,让代理对象实现相同接口
            Class proxyClazz = java.lang.reflect.Proxy.getProxyClass(target.getClass().getClassLoader(), target.getClass().getInterfaces());
            Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
            Object proxy = constructor.newInstance(new InvocationHandler(){
    
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println(method.getName() + "方法开始执行");
                    Object result = method.invoke(target, args);
                    System.out.println(result);
                    System.out.println(method.getName() + "方法执行结束");
                    return result;
                }
            });
            return proxy;
        }
        
        private static Object getProxy1(final Object target) throws Exception{
            Object proxy = Proxy.newProxyInstance(
                    target.getClass().getClassLoader(), //类加载器
                    target.getClass().getInterfaces(), //让代理对象和目标对象实现相同接口
                    new InvocationHandler() {//代理对象的方法最终都会被JVM导向它的invoke方法
                
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println(method.getName() + "方法开始执行");
                    Object result = method.invoke(target, args);
                    System.out.println(result);
                    System.out.println(method.getName() + "方法执行结束");
                    return result;
                }
            });
            return proxy;
        }
    }

    动态的给已有的接口所有实现类添加一个打印日志。

  • 相关阅读:
    【云速建站】购买前的指导
    【云速建站】域名配置指导
    Python爬虫批量下载糗事百科段子,怀念的天王盖地虎,小鸡炖蘑菇...
    舌尖上的安全
    【云速建站】视频播放专题
    Python装饰器总结,带你几步跨越此坑!
    让你提前认识软件开发(15):程序调试的利器—日志
    Win8下IIS的安装和站点的公布
    [2011山东ACM省赛] Mathman Bank(模拟题)
    Android UI开发神兵利器之Android Action Bar Style Generator
  • 原文地址:https://www.cnblogs.com/zhengyuanyuan/p/10749278.html
Copyright © 2011-2022 走看看