• 代理模式


    转自 http://blog.csdn.net/briblue/article/details/73928350

    参考:https://www.jianshu.com/p/58759fef38b8

    一、静态代理

    package com.proxy.test;
    
    /**
     * 首先得有一个接口,通用的接口是代理模式实现的基础。这个接口我们命名为 Movie,代表电影播放的能力
     * @author Yuanjingkun
     *
     */
    public interface Movie {
        void play();
    }
    package com.proxy.test;
    /**
     * 真正实现 Movie接口的类,这个表示真正的影片。它实现了 Movie 接口,play() 方法调用时,影片就开始播放
     * @author Yuanjingkun
     *
     */
    public class RealMovie implements Movie {
    
        @Override
        public void play() {
            System.out.println("您正在观看电影 《肖申克的救赎》");
        }
    
    }
    package com.proxy.test;
    /**
     * 只是实现接口的代理类,Cinema 就是 Proxy 代理对象,它有一个 play() 方法。不过调用 play() 方法时,它进行了一些相关利益的处理,那就是广告。
     * @author Yuanjingkun
     *
     */
    public class Cinema implements Movie {
    
        RealMovie movie;
    
        public Cinema(RealMovie movie) {
            
            this.movie = movie;
        }
    
    
        @Override
        public void play() {
    
            guanggao(true);
    
            movie.play();
    
            guanggao(false);
        }
    
        public void guanggao(boolean isStart){
            if ( isStart ) {
                System.out.println("电影马上开始了,爆米花、可乐、口香糖9.8折,快来买啊!");
            } else {
                System.out.println("电影马上结束了,爆米花、可乐、口香糖9.8折,买回家吃吧!");
            }
        }
    
    }
    package com.proxy.test;
    
    /**
     * @author Yuanjingkun
     *
     */
    public class ProxyTest {
    
        public static void main(String[] args) {
    
            RealMovie realmovie = new RealMovie();
    
            Movie movie = new Cinema(realmovie);
    
            movie.play();
    
        }
    
    }

    结果:

    电影马上开始了,爆米花、可乐、口香糖9.8折,快来买啊!
    您正在观看电影 《肖申克的救赎》
    电影马上结束了,爆米花、可乐、口香糖9.8折,买回家吃吧!

    现在可以看到,代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类。

    二 、动态代理

    package com.frank.test;
    
    public interface SellWine {
    
        /**
         * 卖酒
         */
        void maiJiu();
        
    }
    package com.frank.test;
    
    public interface SellCigarette {
    
        /**
         * 卖烟
         */
        void maiYan();
        
    }
    package com.frank.test;
    
    public class MaotaiJiu implements SellWine{
    
        @Override
        public void maiJiu() {
            
            System.out.println("我卖的是茅台酒");
            
        }
    }
    package com.frank.test;
    
    public class Wuliangye implements SellWine{
    
        @Override
        public void maiJiu() {
            
            System.out.println("我卖的是五粮液");
            
        }
    }
    package com.frank.test;
    
    public class Furongwang implements SellCigarette{
    
        @Override
        public void maiYan() {
            // TODO Auto-generated method stub
            System.out.println("售卖的是芙蓉王,可以扫码查证");
        }
    }
    package com.frank.test;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class GuitaiA implements InvocationHandler{
    
        private Object pinpai;
        
        public GuitaiA(Object pinpai){
            this.pinpai = pinpai;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("销售开始 柜台是:"+this.getClass().getSimpleName());
            method.invoke(pinpai, args);
            System.out.println("销售结束");
            return null;
        }
    }
    package com.frank.test;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class Test {
    
        public static void main(String[] args) {
            
            MaotaiJiu maotaijiu = new MaotaiJiu();
            Wuliangye wuliangye = new Wuliangye();
            Furongwang furongwang = new Furongwang();
            InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);
            InvocationHandler jingxiao2 = new GuitaiA(wuliangye);
            InvocationHandler jingxiao3 = new GuitaiA(furongwang);
            
            SellWine dynamicProxyMaotai = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(), MaotaiJiu.class.getInterfaces(), jingxiao1);
            SellWine dynamicProxyWuliangye = (SellWine) Proxy.newProxyInstance(Wuliangye.class.getClassLoader(), Wuliangye.class.getInterfaces(), jingxiao2);
            SellCigarette dynamicProxyFurongwang = (SellCigarette) Proxy.newProxyInstance(Furongwang.class.getClassLoader(), Furongwang.class.getInterfaces(),jingxiao3);
            dynamicProxyMaotai.maiJiu();
            dynamicProxyWuliangye.maiJiu();
            dynamicProxyFurongwang.maiYan();
            System.out.println(dynamicProxyMaotai.getClass().getName());
        }
    }

    结果:

    销售开始 柜台是:GuitaiA
    我卖的是茅台酒
    销售结束
    销售开始 柜台是:GuitaiA
    我卖的是五粮液
    销售结束
    销售开始 柜台是:GuitaiA
    售卖的是芙蓉王,可以扫码查证
    销售结束
    com.sun.proxy.$Proxy0

    红框中 $Proxy0 就是通过 Proxy 动态生成的。 
    $Proxy0 实现了要代理的接口。 
    $Proxy0 通过调用 InvocationHandler 来执行任务。

    总结

    1. 代理分为静态代理和动态代理两种。
    2. 静态代理,代理类需要自己编写代码写成。
    3. 动态代理,代理类通过 Proxy.newInstance() 方法生成。
    4. 不管是静态代理还是动态代理,代理与被代理者都要实现两样接口,它们的实质是面向接口编程。
    5. 静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。
    6. 动态代理通过 Proxy 动态生成 proxy class,但是它也指定了一个 InvocationHandler 的实现类。
    7. 代理模式本质上的目的是为了增强现有代码的功能。
  • 相关阅读:
    Axiom3D:资源引用与加载基本流程.
    实践:C++平台迁移以及如何用C#做C++包装层
    Axiom3D:Buffer漫谈
    CSS: hover选择器的使用
    TTS 语音修复 ,缺少文件的,没注册类的
    sqlserver 查找某个字段在哪张表里
    Excel 表格查找重复数据,去重复统计
    C# HttpWebResponse WebClient 基础连接已经关闭: 发送时发生错误.
    C# 控件置于最顶层、最底层
    C# 线程 正确使用Thread.Join()停止方式
  • 原文地址:https://www.cnblogs.com/thiaoqueen/p/8054091.html
Copyright © 2020-2023  润新知