用另一种方式来讲解代理模式~

在这里插入图片描述

说起代理模式,我算是对他三进三出了,文章至少写的有两篇了,但是我再去看的时候,总感觉不太容易理解,今天来一个我自己的真实案例,通过暑假实习找房子的经历来进行讲解代理模式。

静态代理
代理模式的话,大致可以分为两种,其一是静态代理,其二是动态代理,静态代理的话,相对简单点。先来一个我暑假的租房场景~

暑假的时候,我一个人来到了杭州,找了一个实习,然后我问HR,附近哪个小区的房子比较不错(第一件事租房),然后他说“福鼎家园”,于时我就来到了福鼎,旁边有一个小房间,好像是暂住证登记的地方,我就问他,这边有房子出租吗?然后他就给我打了个电话,叫过来一个阿姨,然后带我看房子,这些房子是哪来的呢(第二件事房东把房子注册到中介),原来都是房东的房子,只是中介带我看罢了,然后看了好多套房子(第三件事跟着中介看房子),终于看到了一个小房间,我很满意,然后就签了(最后我成功的租到了房子

第一件事,从上面的简单描述可以看出,这一切的一切,都源于你要干一件事,那就是租房子,也就是说,你得有需求。

// 首先要有一个需求,也就是要租房子,这个需求不用实现,让房东和代理去实现
public interface Rent {
    public void rent();
}

第二件事,有了租房的需求,是不是得有房东出租房子呀,要不然也没得租呀。

// 房东实现Rent接口,做出租房子这件事
public class Host implements Rent {
    public void rent() {
        System.out.println("房东出租房子");
    }
}

第三件事,有了房东要出租房子了,代理是不是可以帮助房东了,代理的出现,主要是可以完成房东的一些杂事,例如看房子和“忽悠”,而房东只需出租房子就行了(房东的事情比较单一了)。

public class Proxy implements Rent{
    private Host host;

    public void setHost(Host host) {
        this.host = host;
    }

    public void rent() {
        //这里是代理帮助房东出租房子
        host.rent();
    }
    public void watch() {
		System.out.println("看房子,一家一家又一家,我中介从不怕累。。。");
	}
}

最后成功套娃

public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        Proxy proxy = new Proxy();
        proxy.setHost(host);
        proxy.rent();
    }
}

经过这一波一换五,终于摧毁了敌方的水晶,稳赚不赔,此时房东达到了目的,成功出租房子,中介(代理)达到了目的,成功拿到了中介费,我也达到了目的,成功被中介套路(找到了心仪的房子)。

聪明的小朋友一定会发现一个问题,这里的房东只有一个,也就是Host,而中介也是一个Proxy。聪明的中介可能只做一个房东的代理吗,我觉得不会,汽车跑高速还有备胎呢。那问题来了,一个中介怎么才能代理多个房东呢(脚踏多只船),这个有点难度呀,仔细想想也不难,我一个代理去组合多个房东不就可以了吗(生活经验丰富的你说的没错,但是程序不好写呀。。。)这样一来,也就是每当有新的房东要出租房子的时候,都可以注册到中介这,有那么一丝丝的动态的感觉了,也就是接下来要讲的动态代理。

动态代理
动态代理的牛逼之处,就是代理这个角色,这里通过JDK提供的动态代理来实现,这种方式是基于接口的,还有一种是CGlib,基于类的。
第一件事同样的出租房子这件事不变

// 出租房子的需求
public interface Rent {
    public void rent();
}

第二件事有房东出租房子,也不变

public class Host implements Rent {
    public void rent() {
        System.out.println("房东出租房子");
    }
}

第三件事生成代理类,这个就是动态代理的核心了,通过JDK提供的Proxy类和InvocationHandler接口来实现。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
//该类会自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler{
 
    //被代理的接口
    private Rent rent;
 
    public void setRent(Rent rent) {
        this.rent = rent;
    }
 
    //生成代理类
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
 
    //处理代理程序,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //动态代理的本质,用反射机制
        seeHost();//被扩展的功能可以直接加到这
        Object result = method.invoke(rent,args);
        return result;
    }
 
    //在这里可以扩展功能
    public void seeHost() {
        System.out.println("代理带看房子");
    }
}

最后仍然是成功租到房子


import com.sun.org.apache.regexp.internal.RE;
 
public class Client {
    public static void main(String[] args) {
 
        //这是真实角色,也就是我们的房东
        Host host = new Host();
 
        //创建代理调用处理角色
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
 
        //通过调用程序处理角色来处理我们要调用的接口对象
        proxyInvocationHandler.setRent(host);
 
        //创建代理对象
        Rent proxy = (Rent) proxyInvocationHandler.getProxy();
        proxy.rent();
 
    }

总结
不管是动态代理还是静态代理,其本质都是让“房东”的业务变得单一,只是负责出租房子,一些繁琐的事情例如,看房子,“套娃”,跑腿等,都交给中介做了。这样做的好处是,实现了业务分工,当业务扩展时,方便集中管理

猜你喜欢

转载自blog.csdn.net/HeZhiYing_/article/details/109284813