精华内容
下载资源
问答
  • 秒懂Java代理与动态代理模式

    万次阅读 多人点赞 2018-06-30 17:08:23
    什么是代理模式?解决什么问题(即为什么需要)?什么是静态代理?什么是动态代理模式?二者什么关系?具体如何实现?什么原理?如何改进?这即为我们学习一项新知识的正确打开方式,我们接下来会以此展开,让你秒懂...

    版权申明】非商业目的可自由转载
    博文地址:https://blog.csdn.net/shusheng0007/article/details/80864854
    出自:shusheng007

    设计模式汇总篇,一定要收藏:

    永不磨灭的设计模式(有这一篇真够了,拒绝标题党)

    概述

    什么是代理模式?解决什么问题(即为什么需要)?什么是静态代理?什么是动态代理模式?二者什么关系?具体如何实现?什么原理?如何改进?这即为我们学习一项新知识的正确打开方式,我们接下来会以此展开,让你秒懂。

    类型

    结构型(structural)

    难度

    3颗星

    概念

    什么是代理模式

    定义:为其他对象提供一种代理以控制对这个对象的访问

    定义总是抽象而晦涩难懂的,让我们回到生活中来吧。

    实例:王二狗公司(天津在线回声科技发展有限公司)老板突然在发工资的前一天带着小姨子跑路了,可怜二狗一身房贷,被迫提起劳动仲裁,劳动局就会为其指派一位代理律师全权负责二狗的仲裁事宜。那这里面就是使用了代理模式,因为在劳动仲裁这个活动中,代理律师会全权代理王二狗。

    解决什么问题

    下面是一些使用场景,不过太抽象,暂时可以不要在意,随着你的不断进步你终究会明白的。

    • 远程代理 :为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。
    • 虚拟代理:通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。
    • 缓冲代理:为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。
    • 保护代理:可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。
    • 智能引用:要为一个对象的访问(引用)提供一些额外的操作时可以使用

    什么是静态代理

    静态代理是指预先确定了代理与被代理者的关系,例如王二狗的代理律师方文镜是在开庭前就确定的了。那映射到编程领域的话,就是指代理类与被代理类的依赖关系在编译期间就确定了。下面就是王二狗劳动仲裁的代码实现:

    首先定义一个代表诉讼的接口

    public interface ILawSuit {
        void submit(String proof);//提起诉讼
        void defend();//法庭辩护
    }
    

    王二狗诉讼类型,实现ILawSuit接口

    public class SecondDogWang implements ILawSuit {
        @Override
        public void submit(String proof) {
            System.out.println(String.format("老板欠薪跑路,证据如下:%s",proof));
        }
    
        @Override
        public void defend() {
            System.out.println(String.format("铁证如山,%s还钱","马旭"));
        }
    }
    

    代理律师诉讼类,实现ILawSuit接口

    public class ProxyLawyer implements ILawSuit {
    
        ILawSuit plaintiff;//持有要代理的那个对象
        public ProxyLawyer(ILawSuit plaintiff) {
            this.plaintiff=plaintiff;
        }
    
        @Override
        public void submit(String proof) {
            plaintiff.submit(proof);
        }
    
        @Override
        public void defend() {
            plaintiff.defend();
        }
    }
    

    产生代理对象的静态代理工厂类

    public class ProxyFactory {
        public static ILawSuit getProxy(){
            return new ProxyLawyer(new SecondDogWang());
        }
    }
    

    这样就基本构建了静态代理关系了,然后在客户端就可以使用代理对象来进行操作了。

        public static void main(String[] args) {
            ProxyFactory.getProxy().submit("工资流水在此");
            ProxyFactory.getProxy().defend();
        }
    

    输出结果如下:

    老板欠薪跑路,证据如下:工资流水在此
    铁证如山,马旭还钱
    

    可以看到,代理律师全权代理了王二狗的本次诉讼活动。那使用这种代理模式有什么好处呢,我们为什么不直接让王二狗直接完成本次诉讼呢?现实中的情况比较复杂,但是我可以简单列出几条:这样代理律师就可以在提起诉讼等操作之前做一些校验工作,或者记录工作。例如二狗提供的资料,律师可以选择的移交给法庭而不是全部等等操作,就是说可以对代理的对做一些控制。例如二狗不能出席法庭,代理律师可以代为出席。。。

    什么是动态代理

    动态代理本质上仍然是代理,情况与上面介绍的完全一样,只是代理与被代理人的关系是动态确定的,例如王二狗的同事牛翠花开庭前没有确定她的代理律师,而是在开庭当天当庭选择了一个律师,映射到编程领域为这个关系是在运行时确定的。

    那既然动态代理没有为我们增强代理方面的任何功能,那我们为什么还要用动态代理呢,静态代理不是挺好的吗?凡是动态确定的东西大概都具有灵活性,强扩展的优势。上面的例子中如果牛翠花也使用静态代理的话,那么就需要再添加两个类。一个是牛翠花诉讼类,一个是牛翠花的代理律师类,还的在代理静态工厂中添加一个方法。而如果使用动态代理的话,就只需要生成一个诉讼类就可以了,全程只需要一个代理律师类,因为我们可以动态的将很多人的案子交给这个律师来处理。

    Jdk动态代理实现

    在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler接口、另一个则是 Proxy类,这个类和接口是实现我们动态代理所必须用到的。

    InvocationHandler接口是给动态代理类实现的,负责处理被代理对象的操作的,而Proxy是用来创建动态代理类实例对象的,因为只有得到了这个对象我们才能调用那些需要代理的方法。

    接下来我们看下实例,牛翠花动态指定代理律师是如何实现的。
    1.构建一个牛翠花诉讼类

    public class CuiHuaNiu implements ILawSuit {
        @Override
        public void submit(String proof) {
            System.out.println(String.format("老板欠薪跑路,证据如下:%s",proof));
        }
        @Override
        public void defend() {
            System.out.println(String.format("铁证如山,%s还牛翠花血汗钱","马旭"));
        }
    }
    

    2.构建一个动态代理类

    public class DynProxyLawyer implements InvocationHandler {
        private Object target;//被代理的对象
        public DynProxyLawyer(Object obj){
            this.target=obj;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	    System.out.println("案件进展:"+method.getName());
            Object result=method.invoke(target,args);
            return result;
        }
    }
    

    3.修改静态工厂方法

    public class ProxyFactory {
    	...
    
        public static Object getDynProxy(Object target) {
            InvocationHandler handler = new DynProxyLawyer(target);
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
        }
    }
    

    4.客户端使用

        public static void main(String[] args) {
            ILawSuit proxy= (ILawSuit) ProxyFactory.getDynProxy(new CuiHuaNiu());
            proxy.submit("工资流水在此");
            proxy.defend();
        }
    

    输出结果为:

    案件进展:submit
    老板欠薪跑路,证据如下:工资流水在此
    案件进展:defend
    铁证如山,马旭还牛翠花血汗钱
    

    JDK动态代理实现的原理

    首先Jdk的动态代理实现方法是依赖于接口的,首先使用接口来定义好操作的规范。然后通过Proxy类产生的代理对象调用被代理对象的操作,而这个操作又被分发给InvocationHandler接口的 invoke方法具体执行

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
    

    此方法的参数含义如下
    proxy:代表动态代理对象
    method:代表正在执行的方法
    args:代表当前执行方法传入的实参
    返回值:表示当前执行方法的返回值

    例如上面牛翠花案例中,我们使用Proxy类的newProxyInstance()方法生成的代理对象proxy去调用了proxy.submit("工资流水在此");操作,那么系统就会将此方法分发给invoke().其中proxy对象的类是系统帮我们动态生产的,其实现了我们的业务接口ILawSuit

    cgLib的动态代理实现

    由于JDK只能针对实现了接口的类做动态代理,而不能对没有实现接口的类做动态代理,所以cgLib横空出世!CGLib(Code Generation Library)是一个强大、高性能的Code生成类库,它可以在程序运行期间动态扩展类或接口,它的底层是使用java字节码操作框架ASM实现。

    1 引入cgLib 库
    cglib-nodep-3.2.6.jar:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类.

    2 定义业务类,被代理的类没有实现任何接口

    public class Frank {
       public void submit(String proof) {
           System.out.println(String.format("老板欠薪跑路,证据如下:%s",proof));
       }
       public void defend() {
           System.out.println(String.format("铁证如山,%s还Frank血汗钱","马旭"));
       }
    }
    

    3 定义拦截器,在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。

    public class cgLibDynProxyLawyer implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
            if (method.getName().equals("submit"))
                System.out.println("案件提交成功,证据如下:"+ Arrays.asList(params));
            Object result = methodProxy.invokeSuper(o, params);
            return result;
        }
    }
    

    4定义动态代理工厂,生成动态代理

    public class ProxyFactory {
        public static Object getGcLibDynProxy(Object target){
            Enhancer enhancer=new Enhancer();
            enhancer.setSuperclass(target.getClass());
            enhancer.setCallback(new cgLibDynProxyLawyer());
            Object targetProxy= enhancer.create();
            return targetProxy;
        }
    }
    

    5客户端调用

      public static void main(String[] args) {
            Frank cProxy= (Frank) ProxyFactory.getGcLibDynProxy(new Frank());
            cProxy.submit("工资流水在此");
            cProxy.defend();
        }
    

    输出结果:

    案件提交成功,证据如下:[工资流水在此]
    老板欠薪跑路,证据如下:工资流水在此
    铁证如山,马旭还Frank血汗钱
    

    可见,通过cgLib对没有实现任何接口的类做了动态代理,达到了和前面一样的效果。这里只是简单的讲解了一些cgLib的使用方式,有兴趣的可以进一步了解其比较高级的功能,例如回调过滤器(CallbackFilter)等。

    cgLib的动态代理原理

    CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。

    CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

    CGLIB缺点:对于final方法,无法进行代理。

    动态代理在AOP中的应用

    什么是AOP? 维基百科上如是说:

    定义:In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns.
    AOP是一种编程范式,其目标是通过隔离切面耦合来增加程序的模块化。

    首先声明,AOP是OOP的补充,其地位及其重要性远不及OOP,总体来说OOP面向名词领域而AOP面向动词领域,例如对一个人的设计肯定是使用OOP,例如这个人有手,脚,眼睛瞪属性。而对这个人上厕所这个动作就会涉及到AOP,例如上厕所前的先确定一下拿没拿手纸等。要理解AOP就首先要理解什么是切面耦合(cross-cutting concerns)。例如有这样一个需求,要求为一个程序中所有方法名称以test开头的方法打印一句log,这个行为就是一个典型的cross-cutting场景。首先这个打印log和业务毫无关系,然后其处于分散在整个程序当中的各个模块,如果按照我们原始的方法开发,一旦后期需求变动将是及其繁琐的。所以我们就需要将这个切面耦合封装隔离,不要将其混入业务代码当中。

    例如在王二狗的案子中,我们希望在案子起诉后打印一句成功的log,如果不使用代理的话,我们是需要将log写在相应的业务逻辑里面的,例如王二狗诉讼类SecondDogWang里面的submit()方法中。使用了动态代理后,我们只需要在InvocationHandler 里面的invoke()方法中写就可以了,不会侵入业务代码当中,在以后的维护过程中对业务毫无影响,这是我们希望看到的。

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("submit"))
               System.out.println("案件提交成功,证据如下:"+ Arrays.asList(args));
        Object result=method.invoke(target,args);
        return result;
    }
    

    输出结果为:

    案件提交成功,证据如下:[工资流水在此]
    老板欠薪跑路,证据如下:工资流水在此
    铁证如山,马旭还牛翠花血汗钱
    

    所以AOP主要可以用于:日志记录,性能统计,安全控制,事务处理,异常处理等场景下。

    总结

    静态代理比动态代理更符合OOP原则,在日常开发中使用也较多。动态代理在开发框架时使用较多,例如大名鼎鼎的Spring

    最后希望王二狗和牛翠花他们可以顺利拿回自己的血汗钱。

    GitHub源码地址design-patterns

    展开全文
  • 房地产营销代理机构的发展趋势及商业模式
  • 159商业模式代理制度详解

    千次阅读 2018-08-19 20:36:24
    159素食全餐、德世久一吃黑、魔皱美容等微商分销系统一经推出,立即火爆发展,其爆发增长速度惊人,我们从软件技术的角度来为大家分析一下他们成功的商业模式代理制度或者奖金制度等。 我们以2015年推出至今...

    移动互联网时代,几乎所有的人都离不开互联网,传统企业都在寻求转型,大家都在谈互联网思维,互联网思维已经成为了一个现代化企业的标配,当大家都在大谈互联网思维的时候,到底什么才是互联网思维呢?

    产品品牌商、实体生产企业怎样转型?怎样建立自己的销售平台或者分销直销系统,把产品直接销售到消费者呢?

    159素食全餐、德世久一吃黑、魔皱美容等微商分销系统一经推出,立即火爆发展,其爆发增长速度惊人,我们从软件技术的角度来为大家分析一下他们成功的商业模式、代理制度或者奖金制度等。

    我们以2015年推出至今仍然非常火爆、稳步发展但又非常低调的佐大力159素食全餐的来分析吧。

    首先来看看159的宣传口号:159财富盛宴,你要缺席吗?你要错过吗?

    这里写图片描述

    刚开始159通过各种会议营销,还上到央视及各种地方电视台宣传推广,为线下会议营销吸粉造势。
    这里写图片描述

    159,到底有多火?
    ★爆发速度惊人
    2015年上市,一年时间,销售额从0,增加到每月超过1亿元。
    ★被无数人推崇(159自称)
    人群:养生专家、医生、大师、道长、亿万富翁、灵性导师、行业大咖、百姓
    很多人说:不赚一分钱,我也会去分享159.
    那到底159为什么会这么成功呢?
    159成功揭秘一:产品好
    一个爆款产品是营销的基础,产品必须要有一定的效果,质量也要好,如果是没有效果的劣质产品,就没有口碑相传和回头客了。另外产品的市场足够大,产品新颖,竞争对手少。还有就是性价比高,并且产品的成本足够低,要有足够的利润空间拿出来分润。
    159成功揭秘二:符合趋势
    ★159符合大健康趋势,充分利用了以下概念:健康、养生、食疗、饮食、营养、吃素、放生、修行、能量、大爱等。
    ★159也符合互联网+趋势,手机、微信、微商、社群、移动互联网、互联网国家战略、分享经济等。
    159成功揭秘三:模式好
    其实现代社会,不缺产品,好的产品多的是,并且层出不穷,但往往基于传统模式的销售,无法迅速推广做大做强,所以有好的产品,没有好的商业模式,在现在供过于求的时代,是无法很好地推广和赚到钱的,159商业模式有哪些优点呢?
    ★代理机制:传统代理+二级分销
    ★运作方式
    O2O运作:通过微商软件平台系统,对接微信和社群,线上+线下活动结合
    快速启动:通过会员管理软件系统,体验者瞬间变成经营者,消费变成事业
    倍增裂变:通过分销分润软件系统,实现团队裂变,收入倍增,有被动收入
    系统支持:通过结合以上系统功能的一体化平台软件,实现简单化、可复制

    综合以上分析,可见一个好产品,加上一个好模式,这是成功的关键。那么从技术角度出发,有好产品和好的商业模式, 就必须要有一套好的软件系统来实现这个商业模式才行,这个软件系统是赚钱的工具,没有这个系统工具,一切都是空谈无法落地,找到一套合适的电商分润软件,这才是关键中的关键,这方面我们可以加微交流。

    我们再来详细分析一下159的代理制度,微商系统的商业模式,必须有一个富有吸引力的代理制度及激励机制,才能实现迅速裂变。也必须要有一个明确的制度需求,技术人员才能做出系统功能需求分析书,才能安排软件工程师开始写代码,然后看起来简单的文字,需要转换为软件语言来编写并实现功能应用需要,还是不简单的哦。

    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
    以上为159的代理制度,159的成功有赖于这套制度的吸引力,更加离不开能够实施这套代理制度的软件系统工具。159的代理制度是市面上普通的二级分销、三级分销简单系统无法实现的,必须外包给软件公司定制开发或者自行组建技术团队开发,开发成本比较高。如果是购买简单的分销系统会满足不了需要,数据承载能力低,运行效果差,安全性低,往往达到一定数据量时系统承载不了就需要更换系统,这样损耗和影响会很大。所以一开始就有一套合适的软件系统极为重要,这方面我们可以深度交流探讨一下,加微号:wx_jiangxinyun。
    合适或者理想的软件系统有什么特点呢?首先是数据承载能力强,发展壮大可以一劳永逸不用更换系统;其次是运行速度快,体验感好;最重要的是安全性高,抵御攻击能力强;最后是功能强大,可扩展性强,可以随时根据发展需要增加和修改应用功能,或者是创新功能及商业模式;对了,最好能做到多种终端只用一个数据库管理,比如手机端、PC端、IPAD端、电视端、小程序、微信公众号、苹果APP、安卓APP等各种终端可以统一用一个数据库管理,免得以后需要时每个都是不同的公司开发,不同的代码管理,需要增加人力物力,并且数据不同步等。
    这里写图片描述
    这里写图片描述
    当然,还有其它很多方面都是重要的,必须要搞清楚,篇幅有限,有机会我们一起交流探讨,从软件方面,一个强大的后台及足够的功能模块很重要,最重要的是能够百分百实现既定的商业模式、分润模式或者间接制度。
    这里写图片描述
    其实每个企业、每个产品、面对的客户都会有不同的特性,每个老板都需要设计一套适合自己企业的商业模式和代理机制、分销机制,这方面可以先找行业人士交流咨询,最好让其提供一份系统需求分析书、或者功能需求清单进行参考或者比对,让你了解和比较得明明白白,才能放心确定自己的财富助力工具!
    这里写图片描述
    在互联网+时代,新零售、新模式层出不穷,怎样才能突围而出,搭建自己的营销体系和大数据平台?怎样才能以裂变的模式吸粉和卖出产品呢?欢迎交流讨论。
    这里写图片描述

    展开全文
  • (19)中华人民共和国国家知识产权局 (12)发明专利申请 (10)申请公布号 CN 110889984 A (43)申请公布日 2020.03.17 (21)申请号 201811046656.1 (22)申请日 2018.09.08 (71)申请人 苏州米特希赛尔人工智能有限公司 地址...
  • 设计模式之代理模式(七)

    千次阅读 2018-03-04 11:18:33
    代理模式简介 代理模式定义:为被代理对象提供代理以控制该对象的访问权限。例如我们想找明星出演商业活动的时候是不可以直接联系本人的,是需要联系经纪人。代理模式通用类图入门案例一 例如我想找颖宝去演出某部...

    代理模式

    简介

             代理模式定义:为被代理对象提供代理以控制该对象的访问权限。例如我们想找明星出演商业活动的时候是不可以直接联系本人的,是需要联系经纪人。

    代理模式通用类图

    入门案例一

             例如我想找颖宝去演出某部电视剧,颖宝平时的工作很忙,如果什么事情都要自己处理的话,就会显得很劳累。所以才有明星经纪人的出现,那么经纪人其实就是颖宝的代理人的。代理颖宝处理一部分事情,你要找颖宝就必须通过经纪人。

             那么问题就来了,经纪人总要知道颖宝会那些技能吧!不能随便就接了一些活动,颖宝不会的话那么不就相当于捣乱了吗?还没有分担颖宝的压力。对应到Java代码中,就是经纪人(代理人)和颖宝(被代理人)需要有公共的接口。

    代码

    package com.rabbit.pattern.proxy;
    
    /**
     * 代理人和被代理人共识技能类
     * Created by vip on 2018/3/1.
     */
    public interface Skill {
    
        /**
         * 唱歌
         * @param name
         */
        void sing(String name);
    
        /**
         * 演出
         * @param name
         */
        void perform(String name);
    
        /**
         * 综艺节目
         * @param name
         */
        void variety(String name);
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * 颖宝
     * Created by vip on 2018/3/1.
     */
    public class YingBao implements Skill {
    
        @Override
        public void sing(String name) {
            System.out.println("颖宝唱了一首[" + name + "]");
        }
    
        @Override
        public void perform(String name) {
            System.out.println("颖宝出演了[" + name + "]");
        }
    
        @Override
        public void variety(String name) {
            System.out.println("颖宝上[" + name + "]综艺节目");
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * 颖宝经纪人
     * Created by vip on 2018/3/1.
     */
    public class YingBaoProxy implements Skill {
    
        //保存被代理人的实例
        private Skill yb;
    
        public YingBaoProxy(Skill skill) {
            this.yb = skill;
        }
    
        //代理人实际是让颖宝去做事情
    
        @Override
        public void sing(String name) {
            yb.sing(name);
        }
    
        @Override
        public void perform(String name) {
            yb.perform(name);
        }
    
        @Override
        public void variety(String name) {
            yb.variety(name);
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * Created by vip on 2018/3/1.
     */
    public class Demo {
    
        public static void main(String[] args) {
            YingBaoProxy ybp = new YingBaoProxy(new YingBao());
            ybp.sing("北京北京");
            ybp.perform("陆贞传奇");
            ybp.variety("天天向上");
        }
        
    }
    

    代理模式优缺点

    优点

    职责清晰

             被代理对象只负责自己实际的业务逻辑,不关心其他非本身的职责。并将其他事务可以通过代理类处理。

    高扩展性

             无论被代理对象如何改变,只要代理类和被代理类都实现了统一接口,都不同修改代理类,而且即使扩展了新的被代理类,代理类也可以使用,只要创建代理类的时候传入对应的被代理类对象。

    智能化

             这主要体现在动态代理中,下面会讲解动态代理。如果有兴趣了解Spring的AOP,其实就是使用了动态代理。

    缺点

             如果不合理的使用代理模式,可能会导致请求处理速度变慢,降低并发量。实现代理模式需要额外的工作,这会导致资源的消耗,如果复杂的代理模式可能会降低系统性能。

    代理方式

             在入门案例一中代理类通过构造函数让调用者指定要代理的对象,这其实是一种比较广泛的调用方式,因为这个代理类可以代理任何实现了Skill的类。

    指定代理类

             还是使用入门案例一中的例子,但是被代理类指定代理类,其他代理类如果强行调用将不可以执行。思路:先通过被代理类获取指定的代理对象来访问。

    package com.rabbit.pattern.proxy;
    
    /**
     * 代理人和被代理人共识技能类
     * Created by vip on 2018/3/1.
     */
    public interface Skill {
    
        /**
         * 唱歌
         * @param name
         */
        void sing(String name);
    
        /**
         * 演出
         * @param name
         */
        void perform(String name);
    
        /**
         * 综艺节目
         * @param name
         */
        void variety(String name);
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * 颖宝
     * Created by vip on 2018/3/1.
     */
    public class YingBao implements Skill {
    
        private YingBaoProxy ybp;//颖宝指定的代理人
    
        //获取指定的代理人对象
        public Skill getProxt() {
            ybp = new YingBaoProxy(this);
            return ybp;
        }
    
        @Override
        public void sing(String name) {
            if (ybp == null) {
                System.out.println("请使用指定的代理类");
            } else {
                System.out.println("颖宝唱了一首[" + name + "]");
            }
        }
    
        @Override
        public void perform(String name) {
            if (ybp == null) {
                System.out.println("请使用指定的代理类");
            } else {
                System.out.println("颖宝出演了[" + name + "]");
            }
        }
    
        @Override
        public void variety(String name) {
            if (ybp == null) {
                System.out.println("请使用指定的代理类");
            } else {
                System.out.println("颖宝上[" + name + "]综艺节目");
            }
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * 颖宝经纪人
     * Created by vip on 2018/3/1.
     */
    public class YingBaoProxy implements Skill {
    
        //保存被代理人的实例
        private Skill yb;
    
        public YingBaoProxy(Skill skill) {
            this.yb = skill;
        }
    
        //代理人实际是让颖宝去做事情
    
        @Override
        public void sing(String name) {
            yb.sing(name);
        }
    
        @Override
        public void perform(String name) {
            yb.perform(name);
        }
    
        @Override
        public void variety(String name) {
            yb.variety(name);
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * Created by vip on 2018/3/1.
     */
    public class Demo {
    
        public static void main(String[] args) {
            Skill ybp = new YingBao().getProxt();
            ybp.sing("北京北京");
            ybp.perform("陆贞传奇");
            ybp.variety("天天向上");
        }
        
    }
    

    动态代理

    介绍动态代理之前我们先了解需要使用到的2个类。

    1)Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

     

    2)Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:

    Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。

    Static Class getProxyClass (ClassLoader loader,Class[]interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

    Static Object newProxyInstance(ClassLoaderloader,Class[] interfaces,InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

    package com.rabbit.pattern.proxy;
    
    /**
     * 代理人和被代理人共识技能类
     * Created by vip on 2018/3/1.
     */
    public interface Skill {
    
        /**
         * 唱歌
         * @param name
         */
        void sing(String name);
    
        /**
         * 演出
         * @param name
         */
        void perform(String name);
    
        /**
         * 综艺节目
         * @param name
         */
        void variety(String name);
    
    }
    

    package com.rabbit.pattern.proxy;
    
    /**
     * 颖宝
     * Created by vip on 2018/3/1.
     */
    public class YingBao implements Skill {
    
        @Override
        public void sing(String name) {
            System.out.println("颖宝唱了一首[" + name + "]");
        }
    
        @Override
        public void perform(String name) {
            System.out.println("颖宝出演了[" + name + "]");
        }
    
        @Override
        public void variety(String name) {
            System.out.println("颖宝上[" + name + "]综艺节目");
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
     * 调度处理类,动态代理对象创建时候使用
     * Created by vip on 2018/3/1.
     */
    public class MyInvocationHandler implements InvocationHandler {
    
        private Object obj;//被代理类实例
    
        public MyInvocationHandler(Object obj) {
            this.obj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("代理对象要处理的公共逻辑可以统一写到这里");
            if (method.getName().equalsIgnoreCase("sing")) {
                System.out.println("我已经不在接唱歌的业务了,不好意思");
                return null;
            }
            Object invoke = method.invoke(obj, args);
            return invoke;
        }
    
    }
    

    package com.rabbit.pattern.proxy;
    
    import java.lang.reflect.Proxy;
    
    /**
     * Created by vip on 2018/3/1.
     */
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            Skill yb = new YingBao();
            //创建调度对象
            MyInvocationHandler mih = new MyInvocationHandler(yb);
            //动态代理的方式创建对象
            Skill s = (Skill)Proxy.newProxyInstance(yb.getClass().getClassLoader(), new Class[]{Skill.class}, mih);
            s.sing("小幸运");
            s.perform("陆贞传奇");
            s.variety("天天向上");
        }
        
    }
    

    动态代理的好处

    可能会觉得动态代理在使用的过程中需要额外的代码,例如“创建调度对象”和“动态代理的方式创建对象”这些代码,但是这都是可以继续封装的。动态代理的好处就是对象只有在需要使用的时候才动态代理,这里少了一个YingBaoSKill类,而且对于扩展了SKill类的子类,不需要额外的去创建一个新的类。

    装饰者模式和代理模式

    装饰者模式:http://blog.csdn.net/sinat_32366329/article/details/79392905

    装饰者

    1)  装饰者模式主要是为了增强被装饰者类的功能,可以说是继承的一种替代方案。

    2)  隐藏了被装饰者类的具体实现,对于调用方来说只知道装饰者类。

    代理

    1)  代理模式主要是为了增强被代理类的权限控制。

    2)  隐藏了被代理类具体实现,对于调用方来说只知道代理类。

     

    装饰者模式和代理模式的实现机制都很像,但是为什么一样的机制要区分出2种设计模式呢?可以说是为了单一职责原则不被破坏。因为2个模式的具体职责不一样,如果都叫装饰者模式或者都叫代理模式那么开发人员就区分不出来具体的作用。对于区分出2种职责可以说为了更加容易理解吧!

    展开全文
  • Java设计模式——代理模式

    千次阅读 2015-12-19 22:49:12
    单类图上来说,它和本篇要说的代理模式还真是有些像似。都需要一个公共的接口,还有一些实现类。代理类(包装类)封装了一个接口对象,提供客户端调用。这些都很类似。不过,有一个细节需要我们注意一下,那就是这里...

    前言

      上一篇说到了策略模式。单类图上来说,它和本篇要说的代理模式还真是有些像似。都需要一个公共的接口,还有一些实现类。代理类(包装类)封装了一个接口对象,提供客户端调用。这些都很类似。不过,有一个细节需要我们注意一下,那就是这里的代理类也需要去继承这里的公共接口。而在策略模式中,包装类则不需要这么做。

    概述

      代理模式就是定义一个原对象的代理对象,来帮助原对象和系统之外的业务作沟通。也就是说,如果我们不能直接或是不愿直接去使用原对象,那么我们就可以使用创建一个原对象的代理来进行操作。

     

    版权说明

    著作权归作者所有。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    作者:Q-WHai
    发表日期: 2015年12月19日
    链接:https://qwhai.blog.csdn.net/article/details/50326817
    来源:CSDN
    更多内容:分类 >> 设计模式

     

    模式说明

    举例--话题访问

    1.背景

      现在我们假设我们要构建一个网站。这个网站允许三类用户访问,分别是:普通注册成员、站长管理员、游客。

      那么这个时候,各个不同的访问者对某一网页的内容都有不同的权限。比如,普通注册成员可以访问、发表和评论(回复)一个话题;站长管理员可以访问、发表、评论以及删除一个话题;而游客则只能访问这个网页。

    2.类图

    图-1 代理模式类图

      根据上面例子中的需求,我们可以画出图-1中的类图。不过虽然类图中的三个实现类都有实现接口中所有方法,不过其实这些实现方法却不适合所有的访问者对象。比如,Member虽然有remove方法,不过普通会员并不能真的删除一个话题。所以这个控制就十分有必要了。

    3.代码及说明

    1.公共接口

      在公共接口中需要定义一些访问者的基本行为。分别是访问话题、发表话题、评论话题和删除话题。

     

    public interface Visitor {
    
        public void visit() throws RoleExcption;
        
        public void publish() throws RoleExcption;
        
        public void comment() throws RoleExcption;
        
        public void remove() throws RoleExcption;
    }

     

    2.具体实现类

      本例中具体实现类倒没什么太多的内容,只是重写了实现接口中的方法。

     

    public class Manager implements Visitor {
    
        @Override
        public void visit() {
            System.out.println("我是网站的管理员,我访问了这个主题");
        }
    
        @Override
        public void publish() {
            System.out.println("我是网站的管理员,我发表了一个主题");
        }
    
        @Override
        public void comment() {
            System.out.println("我是网站的管理员,我评论了一个主题");
        }
    
        @Override
        public void remove() {
            System.out.println("我是网站的管理员,我删除了一个主题");
        }
    }

     

    3.代理类

      代理类的作用还是比较重要,和必要的。他们负责来控制一个访问者对话题的行为,防止越权的行为。比如一个游客访问者是不能发表和评论话题的。那么可以通过代理中方法作控制方式来实现。如下:

     

    public class ProxyVisitor implements Visitor {
    
        private Visitor visitor = null;
        
        public ProxyVisitor() {
            // 默认情况是游客
            visitor = new Tourist();
        }
        
        public ProxyVisitor(Visitor _visitor) {
            visitor = _visitor;
        }
        
        @Override
        public void visit() throws RoleExcption {
            visitor.visit();
        }
    
        @Override
        public void publish() throws RoleExcption {
            if (visitor instanceof Tourist) {
                throw new RoleExcption("游客不能发表主题,请先注册帐号");
            }
            
            visitor.publish();
        }
    
        @Override
        public void comment() throws RoleExcption {
            if (visitor instanceof Tourist) {
                throw new RoleExcption("游客不能发表评论,请先注册帐号");
            }
            
            visitor.comment();
        }
    
        @Override
        public void remove() throws RoleExcption {
            if (!(visitor instanceof Manager)) {
                throw new RoleExcption("只有管理员才可以删除主题");
            }
            
            visitor.remove();
        }
    }

     

    4.客户端

      这里我们通过不同的访问者进行不同的操作,观察结果。

     

    public class VisitorClient {
    
        public static void main(String[] args) {
            Manager manager = new Manager();
            Member member = new Member();
            Tourist tourist = new Tourist();
            
            ProxyVisitor visitor = null;
            System.out.println("------------------- 1 --------------------");
            try {
                visitor = new ProxyVisitor(manager);
                visitor.visit();
                visitor.publish();
                visitor.comment();
                visitor.remove();
            } catch (RoleExcption e) {
                System.err.println(e);
            }
            ThreadUtils.sleep(50);
            
            System.out.println("------------------- 2 --------------------");
            try {
                visitor = new ProxyVisitor(member);
                visitor.visit();
                visitor.publish();
                visitor.comment();
                visitor.remove();
            } catch (RoleExcption e) {
                System.err.println(e);
            }
            ThreadUtils.sleep(50);
            
            System.out.println("------------------- 3 --------------------");
            try {
                visitor = new ProxyVisitor(tourist);
                visitor.visit();
                visitor.publish();
                visitor.comment();
                visitor.remove();
            } catch (RoleExcption e) {
                System.err.println(e);
            }
        }
    }

     

    5.测试结果

    图-2 网站访问代理测试结果

     

    举例--学生考试

    1.背景

      我们都经历过学生时代,也都有考过试,当然也都有作过弊(什么?你没有作过弊?那当我没说...)。

      学生考试是一个公开的行为,而学生作弊却不能公开。所以,我们的考试方法是公有的,而作弊却是私有的。可是,如果我们的客户端程序需要我们在考试的时候来作一下弊。要怎么办呢?你可能会说,这好办,反射啊。的确是这样的,是要用到反射。不过这个反射我们封装在了代理类里面了,再从代理类里把这个方法打成公开的方法。在下面的类图中也会体现。

    2.类图

      这个类图跟上面话题访问者的类图很像。不过还是有一个地方不一样,发现了没有?那就是实现类中有一个比接口类中多出的方法cheat(作弊),且是一个私有的方法,不过在代理类里,这个方法被打成了公开的了。

    图-3 代理模式类图

    3.代码及说明

    1.公共接口

    说明同上

     

    public interface Student {
    
        public void examinate();
        
        public void announce();
        
    }

     

    2.具体实现类

    说明同上

     

    public class SeniorStudent implements Student {
    
        private String name = "";
        private int score = 0;
        
        public SeniorStudent(String _name) {
            name = _name;
        }
        
        @Override
        public void examinate() {
            score = NumberUtils.randomInteger(40, 150);
        }
    
        @SuppressWarnings("unused")
        private void cheat() {
            System.out.println(name + "正在作弊...嘘...");
            score += (NumberUtils.randomInteger(150 - score));
        }
    
        @Override
        public void announce() {
            System.out.println(name + "考了" + score + "分");
        }
    
    }

     

    3.代理类

    注意看这里的cheat方法,是一个公开的方法。在这个方法里,使用了Java的反射来实现对具体实现类的私有方法进行访问。

     

    public class StudentProxy implements Student {
    
        private Student student = null;
    
        public StudentProxy(Student _student) {
            student = _student;
        }
    
        @Override
        public void examinate() {
            student.examinate();
        }
    
        @Override
        public void announce() {
            student.announce();
        }
    
        public void cheat() throws ClassNotFoundException, NoSuchMethodException,
                SecurityException, IllegalAccessException, IllegalArgumentException,
                InvocationTargetException {
            Class<?> clazz = Class.forName(student.getClass().getName());
            Method method = clazz.getDeclaredMethod("cheat");
            method.setAccessible(true);
            method.invoke(student);
        }
    }


    4.客户端

    说明同上

     

    public class StudentProxyClient {
    
        public static void main(String[] args) {
            StudentProxy proxy = new StudentProxy(new Pupil("小明"));
            proxy.examinate();
            proxy.announce();
    
            try {
                proxy.cheat();
            } catch (ClassNotFoundException | NoSuchMethodException
                    | SecurityException | IllegalAccessException
                    | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
    
            proxy.announce();
        }
    }


    5.测试结果

    图-4 学生考试代理测试结果

    GitHub源码下载

    https://github.com/qwhai/design-pattern

    展开全文
  • 设计模式:代理模式

    千次阅读 2013-05-08 09:35:42
    代理模式 一、引子   我们去科技市场为自己的机器添加点奢侈的配件,很多DIYer 都喜欢去找代理商,因为  在代理商那里拿到的东西不仅质量有保证,而且价格和售后服务上都会好很多。客户通过代  理商...
  • JavaScript设计模式之代理模式

    千次阅读 2019-01-20 17:25:35
    代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。 代理模式是一种非常有意义的模式,在生活中可以找到很多代理模式的场景。比如,明星都有经纪人作为代理。如果想请明星来办一场商业演出,只能...
  • 商业模式画布

    万次阅读 多人点赞 2018-07-22 18:52:11
    周四周五机缘巧合参加了一场关于商业模式画布的培训,第一次参加趋向于商业方向的培训,一开始并没有抱太大的期望。但是听完两天的课之后,第一次给培训的老师全是满分的评价,因为确实内容非常受用,两天的课程中即...
  • 绿电交易模式商业区电动汽车代理商定价策略及EV充电管理.pdf
  • 这是我上个月在内部做分析时的一张ppt里的内容,我给大家讲讲。(1)IBM解决方案商业模式IBM模式是带头大哥模式,我来做解决方案、我来做总销售、我来做总包项目管理。所以...
  • C语言和设计模式(代理模式

    万次阅读 2011-12-25 08:16:39
     代理模式是一种比较有意思的设计模式。它的基本思路也不复杂。举个例子来说,以前在学校上网的时候,并不是每一台pc都有上网的权限的。比如说,现在有pc1、pc2、pc3,但是只有pc1有上网权限,但是pc2、pc3也想上网...
  • 代理模式

    千次阅读 2008-06-26 23:07:00
    在这些单位工作的人员均可称为代理人。代理人的共同特征是可以代替委托人去和第三方通信。譬如:律师代替委托人打官司,猎头代替委托人物色人才,红娘代替委托人寻找对象,房产代理人代替委托人出租房屋。代理人可以...
  • 商业模式

    千次阅读 2009-09-20 23:10:00
    概述早在20个世纪50代就有人提出了“商业模式”的概念,但直到40年后(1990年代)才流行开来。[4]泰莫斯定义商业模式是指一个完整的产品、服务和信息流体系,包括每一个参与者和其在其中起到的作用,以及每一个参与...
  • 一、引子 我们去科技市场为自己的机器添加点奢侈的配件,很多DIYer都喜欢去找代理商,因为在代理商那里拿到的东西...看来代理商在商业运作中起着很关键的作用。 不小心把话题扯远了,回过头来,那么在我们的面向对象的
  • 大数据商业模式

    万次阅读 2018-07-18 15:25:46
    难懂的商业模式 互联网时代的到来,我们似乎越来越看不懂现在的商业模式。为什么我们免费使用百度搜索,这家公司还可以有如此高的收入?为什么不拥有一辆出租车的UBER(优步)成了最大出行平台,不拥有一个房间的...
  • 互联网十大商业模式

    千次阅读 2014-09-13 13:46:34
    互联网十大商业模式   第一类 传统门户    [ 观点 ]     门户网站,本质上说就是一个信息管理平台,是一个信息“大杂烩”的入口。随着互联网技术的发展,网络商务活动增多,门户网站越来越多地被用于...
  • 15.3 代理模式应用实例  下面通过一个应用实例来进一步学习和理解代理模式。  1. 实例说明  某软件公司承接了某信息咨询公司的收费商务信息查询系统的开发任务,该系统的基本需求如下:  (1) ...
  • 互联网商业模式

    千次阅读 2018-01-12 16:56:16
    随着互联网技术的发展,网络商务活动增多,门户网站越来越多地被用于商业活动中,对以信息服务为主的门户商业模式的探索也在日益白热化。各种应用系统、数据资源和互联网资源在这里可以快速地完成企业对客户、企业对...
  • 一、引子 我们去科技市场为自己的机器添加点奢侈的配件,很多DIYer都喜欢去找代理商,因为在代理商那里拿到...看来代理商在商业运作中起着很关键的作用。不小心把话题扯远了,回过头来,那么在我们的面向对象的程序设
  • 互联网+商业模式

    千次阅读 2018-12-12 11:32:29
    大数据商业模式 10种商业模式 一、人工智能:数据+物体=智能 人工智能是数据变现的最好方式,但是目前是2B的智能买单意愿更强 GDP*20%。 数据是为人服务的,人接触最多的是物体; 数据的智慧将延伸人的五官,...
  • 深入浅出代理模式

    千次阅读 2004-12-14 20:41:00
    关键字:代理模式 java 一、引子我们去科技市场为自己的机器添加点奢侈的配件,很多DIYer都喜欢去找代理商,因为在代理商那里拿到的东西不仅质量有保证,而且价格和售后服务上都会好很多。客户通过代理商得到了自己...
  • APP的9种商业模式图解

    万次阅读 2017-02-07 17:49:35
    和其他的事业一样,还是要先思考什么是正确的商业模式,才会让创意与技术发挥最大的商业价值。  也许有人会问App的商业模式不就是〝收费〞或〝免费但附广告〞这两种?,当然不只这么简单。借用老祖宗的说法太极生...
  • 第6章代理模式  代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。 代理模式是一种非常有意义的模式,在生活中可以找到很多代理模式的场景。比如明星都有经济人作为代理。如果想请明星来办一场...
  • 分销商管理--代理模式

    千次阅读 2015-12-14 16:49:51
    代理模式:为其他对象提供一种代理以控制这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
  • 商业模式vs盈利模式vs收入流等 怎么干活的(商业模式)怎么赚钱的(盈利模式);商业模式是吸引客户、留存客户、转化客户,各个角色之间配合和转化方式。盈利模式是收费方式。 什么是商业模式,我认为应该包含两个...
  • OTO电子商务商业模式探析

    千次阅读 2015-12-14 22:02:49
     OTO(O2O),即Online to Offline,是将线下商务机会与线上互联网结合在一起,让互联网成为线下交易前台的一种电子商务商业模式,简单来说就是“线上拉客,线下消费”。其核心理念是通过电子商务网站,把线上用户...
  • 10分钟看懂动态代理设计模式

    万次阅读 多人点赞 2018-03-14 10:38:00
    原文作者:欧阳锋点击打开链接动态代理是Java语言中非常经典的一种设计模式,也是所有设计模式中最难理解的一种。本文将通过一个简单的例子模拟JDK动态代理实现,让你彻底明白动态代理设计模式的本质,文章中可能会...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,985
精华内容 18,394
关键字:

商业代理模式