《大话设计模式》——读后感 (4)为别人做嫁衣?——动态代理模式(2)

来源:互联网 发布:prezi 5.2.3 for mac 编辑:程序博客网 时间:2024/06/06 08:50

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

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存在某种,它们之间本来就有耦合,根本不是你使用动态代理设计模式导致的。

 

阅读全文
0 0
原创粉丝点击