zoukankan      html  css  js  c++  java
  • 【结构型模式】《大话设计模式》——读后感 (4)为别人做嫁衣?——动态代理模式(2)

    静态代理无法代理真实实体比较多的情况,那我们还以静态代理的例子开始:

    GiveGift接口:

    package com.sjmx.dynomicProxy.first;
    
    public interface GiveGift {
    
        String giveDolls();
        String giveFlows();
        String giveChocolate();
        
    }

    真实实体:

    package com.sjmx.dynomicProxy.first;
    
    public class Pursuit implements GiveGift {
        
        SchoolGirl girl;
        private String name;
        
        public Pursuit(String name ,SchoolGirl girl){
            this.girl = girl;
            this.name = name;
        }
        
        @Override
        public String giveDolls() {
            String rsg = girl.getName() + ","+ this.name +"送你一个dolls";
            return rsg;
        }
    
        @Override
        public String giveFlows() {
            String rsg = girl.getName() + ","+ this.name +"送你一个Flows";
            return rsg;
        }
    
        @Override
        public String giveChocolate() {
            String rsg = girl.getName() + ","+ this.name +"送你一个Chocolate";
            return rsg;
        }
    
    }

    SchoolGirl:

    package com.sjmx.dynomicProxy.first;
    
    public class SchoolGirl {
        
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
    }

    接下来才是关键,动态代理类出场:

    package com.sjmx.dynomicProxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class MyDynomic implements InvocationHandler{
        
        public Object obj;
        
        public MyDynomic(Object obj) {
            this.obj = obj;
        }
        
        public static Object getDynomicMethod(Object realObj){
            return  Proxy.newProxyInstance(realObj.getClass().getClassLoader()
                        ,realObj.getClass().getInterfaces(),new MyDynomic(realObj));
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object o = method.invoke(obj, args);
            return o;
        }
    }

    客户端如下:

    package com.sjmx.dynomicProxy;
    
    import com.sjmx.dynomicProxy.first.GiveGift;
    import com.sjmx.dynomicProxy.first.Pursuit;
    import com.sjmx.dynomicProxy.first.SchoolGirl;
    import com.sjmx.dynomicProxy.sec.ForefinPursuit;
    
    public class Client {
        
        public static void main(String[] args) {
            
            SchoolGirl girl = new SchoolGirl();
            girl.setName("凌风");
            Pursuit p = new Pursuit("章程", girl);
           
           GiveGift gift = (GiveGift) MyDynomic.getDynomicMethod(p);
           System.out.println(gift.giveChocolate());
           System.out.println(gift.giveDolls());
           System.out.println(gift.giveFlows()); 
        }
        
    }

    运行结果:

    接着我们继续把静态代理遇到的问题拿出来进行验证,如果GiveGift接口有多个实现,那么我们是否可以用使用同一个代理类就搞定呢?现在柯南出现情敌了,我们看看能够正常实现

    新增实现类:

    package com.sjmx.dynomicProxy.sec;
    
    import com.sjmx.dynomicProxy.first.GiveGift;
    import com.sjmx.dynomicProxy.first.SchoolGirl;
    
    public class ForefinPursuit implements GiveGift {
    
        SchoolGirl girl;
        private String name;
        
        public ForefinPursuit(String name ,SchoolGirl girl){
            this.girl = girl;
            this.name = name;
        }
        
        @Override
        public String giveDolls() {
            String rsg = girl.getName() + ","+ this.name +"give you dolls";
            return rsg;
        }
    
        @Override
        public String giveFlows() {
            String rsg = girl.getName() + ","+ this.name +"give you Flows";
            return rsg;
        }
    
        @Override
        public String giveChocolate() {
            String rsg = girl.getName() + ","+ this.name +"give you Chocolate";
            return rsg;
        }
    }

    修改客户端:

    package com.sjmx.dynomicProxy;
    
    import com.sjmx.dynomicProxy.first.GiveGift;
    import com.sjmx.dynomicProxy.first.Pursuit;
    import com.sjmx.dynomicProxy.first.SchoolGirl;
    import com.sjmx.dynomicProxy.sec.ForefinPursuit;
    
    public class Client {
        
        public static void main(String[] args) {
            
            SchoolGirl girl = new SchoolGirl();
            girl.setName("凌风");
            Pursuit p = new Pursuit("柯南", girl);
            
             GiveGift gift = (GiveGift) MyDynomic.getDynomicMethod(p);
             System.out.println(gift.giveChocolate());
             System.out.println(gift.giveDolls());
             System.out.println(gift.giveFlows()); 
             
             ForefinPursuit p2 = new ForefinPursuit("小王", girl);
             GiveGift gift2 = (GiveGift) MyDynomic.getDynomicMethod(p2);
             System.out.println(gift2.giveChocolate());
             System.out.println(gift2.giveDolls());
             System.out.println(gift2.giveFlows());          
        }
        
    }

    运行结果:

    最后,分析一下代码:

    1、动态代理一个代理类,可以代理多个不同的实体,大大简化了代码量

    2、不知道你有没有发现,静态代理的客户端只知道代理类,就能把礼物送给喜欢的女孩子;而动态代理呢?客户端还要知道替谁送的礼物,比如上面的代码,客户端就需要知道ForefinPursuit p2 = new ForefinPursuit("小王", girl);和 Pursuit p = new Pursuit("柯南", girl);这样的话,不知道代码的耦合度是不是增加了呢?

    3、纠结了吧?实际问一个问题,隔壁班你的好朋友想追你们班的班花,你答应帮忙;如果隔壁班的陌生人想追,你会帮忙吗?肯定不会呀,除非你是脑子有病。如果你就是client,而好朋友就是实体A,陌生人就是实体B,因为client是认识 A的,所以会帮忙,而client不认识B,所以不会代替B去做任何事情。细想一下,因为client是认识 A,因为client和 A存在某种,它们之间本来就有耦合,根本不是你使用动态代理设计模式导致的。

  • 相关阅读:
    超级庄家吕梁和中国股市第一案
    汉唐的丧钟
    最牛营业部——国信泰然九路揭秘
    PMBOK
    挣值管理(PV、EV、AC、SV、CV、SPI、CPI)
    没有理智的欲望会走向毁灭,没有欲望的理智会永守清贫
    安信证券行业分析师离职风波评论
    知名证券分析师
    【Python】排列组合itertools & 集合set
    测试&标准说明文章
  • 原文地址:https://www.cnblogs.com/chen1-kerr/p/7058255.html
Copyright © 2011-2022 走看看