前言:
想学习好java,我想是绕不过去设计模式这个坎的,所以今天就代理模式以及动态代理和静态代理给大家讲解一下。这篇文章我们从什么是代理模式,代理模式的作用,有哪几种代理模式来展开讲解!
正文:
一、什么是代理模式
代理模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的组成:
抽象角色 | 通过接口或抽象类声明真实角色实现的业务方法 |
代理角色 | 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。 |
真实角色 | 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用 |
代理模式的结构图 :
抽象角色类,定义了真实角色和代理角色的共用接口,这样就在任何使用真实角色的地方都可以使用代理角色。
举个例子说明,假如说现在我想吃饭,但是吃饭的地方要走一段距离,我又懒得动了,这时候我就可以通过外卖平台来点餐,他们帮我把附近的饭陈列出来,然后并把我想吃的饭送到家。我只需要选择我喜欢吃的饭,然后付钱就可以啦。
1.创建抽象角色接口
public interface BuyFood {
void buyFood();
}
2.创建真实角色
public class BuyFoodImpl implements BuyFood {
@Override
public void buyFood() {
System.out.println("我要买土豆回锅肉盖饭");
}
}
3.创建代理角色
public class BuyFoodProxy implements BuyFood {
private BuyFoodImpl buyFood;
public BuyFoodProxy() {
buyFood=new BuyFoodImpl();
}
@Override
public void buyFood() {
System.out.println("去饭店取土豆回锅肉盖饭");
buyFood.buyFood();
System.out.println("请好好用餐");
}
}
4.客户端代码
public class Client {
public static void main(String[] args) {
BuyFoodProxy buyFoodProxy = new BuyFoodProxy();
buyFoodProxy.buyFood();
}
}
执行结果:
去饭店取土豆回锅肉盖饭
我要买土豆回锅肉盖饭
请好好用餐
这样外卖平台就帮我买到饭啦,我也不用亲自下楼买饭啦。
二、代理模式的作用
1.职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
2.代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
3.高扩展性
4.开闭原则,增加功能
我们可以通过代理角色的代码里加功能来扩展真实角色的功能,这样我们只需要修改代理角色而不需要在修改委托角色,符合代码设计的开闭原则。
三、代理的分类
根据以上对代理的理解,对于代理的具体实现,我们有不同的方式,如果按照代理的创建时期,代理类可以分为两种:静态代理和动态代理。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建的。
上面的第一个例子就是静态代理。
那么换成动态代理的写法:
1.编写动态处理器
public class DynamicProxyHandler implements InvocationHandler{
private Object object;
public DynamicProxyHandler (Object object){
this.object=object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("去饭店取土豆回锅肉盖饭");
Object invoke = method.invoke(object, args);
System.out.println("请好好用餐");
return invoke;
}
}
2.客户端代码
public class DynamicProxyClient {
public static void main(String[] args) {
BuyFoodImpl buyFood = new BuyFoodImpl();
BuyFood proxyBuyFood = (BuyFood)Proxy.newProxyInstance(BuyFood.class.getClassLoader(), new Class[]{BuyFood.class}, new DynamicProxyHandler(buyFood));
proxyBuyFood.buyFood();
}
}
注意Proxy.newProxyInstance()方法接受三个参数:
ClassLoader loader
:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
Class<?>[] interfaces
:指定目标对象实现的接口的类型,使用泛型方式确认类型
InvocationHandler:指定
动态处理器,
执行目标对象的方法时,会触发事件处理器的方法
总结:
今天代理模式就讲到这里,还有很多设计模式需要我们去理解,我们一定要反复去理解,反复去看,并尽量思考是否可以把这些设计模式应用到实际开发中。一开始不明白也无所谓,反复去和同事讲和基友讲,讲的多了,也许你发现哪天醒来就理解啦。
我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有350位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言。