代理模式是一种结构型设计模式,它可以让我们通过一个代理对象来访问一个真实的目标对象,从而实现对目标对象的功能扩展或保护。代理模式的主要角色有三个:
抽象主题(Subject):定义了真实主题和代理主题的公共接口,使得在任何使用真实主题的地方都可以使用代理主题。真实主题(RealSubject):实现了抽象主题的接口,定义了真实的业务逻辑,是代理主题所代表的真实对象。代理主题(Proxy):也实现了抽象主题的接口,但是在调用真实主题的方法之前或之后,可以执行一些额外的操作,从而对真实主题进行控制或增强。代理模式可以帮助我们解决以下几种问题:
(资料图片)
根据代理模式的定义,我们可以用以下的类图来表示它的结构:
其中,Client是客户端类,它需要使用Subject接口提供的方法。Proxy是代理类,它持有一个RealSubject的引用,并且实现了Subject接口。RealSubject是真实类,它也实现了Subject接口,并且定义了具体的业务逻辑。
代理模式有多种类型,例如静态代理、动态代理等,代理模式也有自己的优缺点,使用时需要根据具体的场景和需求来选择合适的类型和方式。
静态代理实现下面我们用Java代码来实现一个静态代理的例子:
// 抽象主题接口public interface Subject { // 定义一个抽象方法 void request();}// 真实主题类public class RealSubject implements Subject { // 实现抽象方法 @Override public void request() { // 真实的业务逻辑 System.out.println("RealSubject is doing something..."); }}// 代理主题类public class Proxy implements Subject { // 持有一个真实主题的引用 private RealSubject realSubject; // 构造方法,传入一个真实主题对象 public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } // 实现抽象方法 @Override public void request() { // 在调用真实主题之前,可以执行一些额外操作 System.out.println("Proxy is doing something before..."); // 调用真实主题的方法 realSubject.request(); // 在调用真实主题之后,可以执行一些额外操作 System.out.println("Proxy is doing something after..."); }}// 客户端类public class Client { public static void main(String[] args) { // 创建一个真实主题对象 RealSubject realSubject = new RealSubject(); // 创建一个代理对象,并传入真实主题对象 Proxy proxy = new Proxy(realSubject); // 使用代理对象来调用抽象方法 proxy.request();}}
运行结果如下:Proxy is doing something before...RealSubject is doing something...Proxy is doing something after...
从运行结果可以看出,代理对象在调用真实对象的方法之前和之后,都执行了一些额外的操作,从而对真实对象进行了增强或控制。
动态代理实现动态代理是一种特殊的代理模式,它可以在运行时动态地创建代理对象,而不需要事先定义代理类。动态代理可以更灵活地适应不同的场景和需求,但是也更复杂和难以理解。
这个例子是使用JDK动态代理来实现一个日志代理,它可以在调用目标对象的方法之前和之后,记录相关的日志信息。代码如下:
// 抽象主题接口public interface Subject { // 定义一个抽象方法 void request();}// 真实主题类public class RealSubject implements Subject { // 实现抽象方法 @Override public void request() { // 真实的业务逻辑 System.out.println("RealSubject is doing something..."); }}// 日志处理器类,实现了InvocationHandler接口,用于定义代理逻辑public class LogHandler implements InvocationHandler { // 持有一个目标对象的引用 private Object target; // 构造方法,传入一个目标对象 public LogHandler(Object target) { this.target = target; } // 实现invoke方法,用于调用目标对象的方法,并在之前和之后执行日志操作 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在调用目标对象之前,记录开始时间 long startTime = System.currentTimeMillis(); System.out.println("开始执行" + method.getName() + "方法..."); // 调用目标对象的方法,并获取返回值 Object result = method.invoke(target, args); // 在调用目标对象之后,记录结束时间和耗时 long endTime = System.currentTimeMillis(); long duration = endTime - startTime; System.out.println("结束执行" + method.getName() + "方法,耗时" + duration + "毫秒"); // 返回结果 return result; }}// 客户端类public class Client { public static void main(String[] args) { // 创建一个真实主题对象 RealSubject realSubject = new RealSubject(); // 创建一个日志处理器对象,并传入真实主题对象 LogHandler logHandler = new LogHandler(realSubject); // 使用Proxy类的静态方法newProxyInstance来动态地创建一个代理对象,传入真实主题对象的类加载器、接口和处理器 Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), logHandler); // 使用代理对象来调用抽象方法 proxy.request(); }}
运行结果如下:
开始执行request方法...RealSubject is doing something...结束执行request方法,耗时1毫秒
从运行结果可以看出,代理对象在调用真实对象的方法之前和之后,都执行了一些日志操作,从而对真实对象进行了增强。
优缺点静态代理模式优点:
代理模式可以实现对真实对象的功能扩展或保护,而不需要修改原有的对象,符合开闭原则。代理模式可以实现对真实对象的访问控制或延迟加载,提高系统的性能和安全性。代理模式可以实现对真实对象的透明访问,客户端只需要使用抽象主题的接口,而不需要关心真实对象和代理对象的细节。缺点:
代理模式会增加系统的复杂度和开销,因为需要创建和维护代理对象。代理模式可能会降低系统的响应速度,因为每次调用真实对象的方法都需要经过代理对象。动态代理模式优点:
动态代理可以在运行时动态地创建代理对象,而不需要事先定义代理类,这样可以减少代码量和提高开发效率。动态代理可以根据不同的目标对象和需求,灵活地生成不同的代理对象,这样可以增加系统的可扩展性和可维护性。动态代理可以实现对目标对象的透明访问,客户端只需要使用抽象主题的接口,而不需要关心真实对象和代理对象的细节。缺点:
动态代理需要使用反射和字节码技术来生成代理对象,这样会增加系统的复杂度和开销,也可能会影响系统的性能和稳定性。动态代理需要遵循一些约束和限制,例如JDK动态代理只能代理实现了接口的类,CGLIB动态代理不能代理final类或方法等,这样会降低系统的灵活性和通用性。动态代理比静态代理更难以理解和掌握,需要有一定的基础知识和经验才能使用好动态代理。运用场景当我们需要访问一个远程对象时,可以使用远程代理,它可以隐藏远程对象的位置和通信细节,让客户端像访问本地对象一样访问远程对象。当我们需要创建一个开销很大的对象时,可以使用虚拟代理,它可以在真正需要的时候才创建真实对象,从而实现延迟加载和节省资源。当我们需要给一个对象增加一些额外的功能时,可以使用装饰代理,它可以在不修改原有对象的情况下,给对象添加一些新的行为或属性。当我们需要给一个对象增加一些访问控制或安全保护时,可以使用保护代理,它可以根据不同的用户或角色,对对象的访问进行限制或检查。当我们需要给一个对象增加一些日志记录或性能监控时,可以使用日志代理或性能代理,它可以在调用对象的方法之前或之后,记录相关的信息或数据。总结代理模式是一种常用的结构型设计模式,它可以让我们通过一个代理对象来间接访问一个真实对象,从而实现对目标对象的功能扩展或保护。代理模式有三个主要角色:抽象主题、真实主题和代理主题。代理模式有多种类型,例如静态代理、动态代理、远程代理、虚拟代理等。代理模式有自己的优缺点,使用时需要根据具体的场景和需求来选择合适的类型和方式。
标签:
简介代理模式是一种结构型设计模式,它可以让我们通过一个代理对象来访问一个真实的目标对象,从而实现对目
近日,四川郎酒股份有限公司(简称“郎酒”)在主会场郎酒庄园和23个分会场举行了第三届郎酒庄园三品节...
5月8日,海德股份(000567)融资买入961 83万元,融资偿还936 59万元,融资净买入25 24万元,融资余额2 72
“五一”假期,除了长途跋涉游历于各大景点,感受祖国大好河山和文化魅力。邀三五好友来到近郊,来一场...
《人生路不熟》票房破7亿累计观影人次1682万
“共有从前,各有未来。”5月8日,演员杨幂官宣与嘉行传媒“分手”。尽管嘉行传媒发文“珍重安好”,但...
证券时报记者沈宁昨日,百亿私募稳博投资在官微发布声明,就前员工在个人直播中对公司的系列质疑进行回应。
5月8日,据住房和城乡建设部官网消息,住房和城乡建设部、市场监管总局两部门联合印发《关于规范房地产经纪
日前,IBM的CEO阿尔温德·克里希纳表示,公司预计将暂停招聘未来几年可能被人工智能所取代的职位。IBM的人
周燕妮表示:“说的很有道理,但是大众不会那么做,因为骂文化人没风险,骂有权的有风险。有一点感触很...
中新网香港5月8日电由紫荆文化集团主办的“国风国韵飘香江”系列活动之中央歌剧院音乐大师课,8日在香港...
三湘都市报·新湖南客户端5月8日讯(文 视频全媒体记者杨昱通讯员杨妮)5月8日是第30个“世界地贫日”...
想必现在有很多小伙伴对于怎么制作旋转的动态数学课件方面的知识都比较想要了解,那么今天小好小编就为大家
今天是高考倒计时30天,各位准“小蓝鲸”们,是否都在摩拳擦掌、跃跃欲试了呢?,今年南京大学本科招生...
征地,邗江区公道镇有地块即将拆迁!,征地,拆迁,征收,邗江区,公道镇
在互动问答环节,有投资者提问公司在医药行业中有哪些核心竞争力?公司独立董事焦磊鹏回答,从成立至今,我
近日,市民谭先生在南京江宁区的乾通哈弗汽车4S店购买了一辆哈弗SUV,因为4S店突然关门,车辆合格证抵押在
如今的汽车市场“内卷”到底有多严重,其实从很多车型价格的妥协我们就完全可以看出来。尤其是对于很多...
2023年5月8日,泰恩康发生1笔大宗交易,总成交30万股,成交金额800 4万元,成交价26 68元,折价20 64%。
为贯彻落实党的二十大关于“深入开展法治宣传教育,增强全民法治观念”部署要求,推动普法强基补短板专...
X 关闭
X 关闭