【结构型模式】《大话设计模式》——读后感 (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存在某种,它们之间本来就有耦合,根本不是你使用动态代理设计模式导致的。

原文地址:https://www.cnblogs.com/chen1-kerr/p/7058255.html