【设计模式】代理模式,韩顺平java数据结构笔记

long startTime = System.currentTimeMillis();

Boolean login = super.login(username, password);

long endTime = System.currentTimeMillis();

System.out.println(“login time : " + (endTime - startTime) +” ms" );

return login;

}

}

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: Test

  • @Author: 流星007

  • @Description: test

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:15

  • @Version: 1.0

*/

public class Test {

public static void main(String[] args) {

UserServiceProxy userServiceProxy = new UserServiceProxy();

Boolean login = userServiceProxy.login(“zhgnsan”, “123456”);

System.out.println("login result : " +login);

}

}

username:zhgnsan

password:123456

login time : 0 ms

login result : true

Process finished with exit code 0

UserService:被代理类,UserServiceProxy:代理类,请求先经过代理类,然后由代理类去操作被代理类,最终记录时间,这样就可以在不改变原来代码的情况下新增功能,是不是很方便。

组合模式的静态代理


刚刚讲解了怎么利用继承实现一个静态代理模式,那现在再来讲解另外一种基于组合模式实现静态代理,改造代码开始

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: IUserService

  • @Author: 流星007

  • @Description: user interface

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:26

  • @Version: 1.0

*/

public interface IUserService {

Boolean login(String username,String password);

}

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: UserService

  • @Author: 流星007

  • @Description: user login or register

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:10

  • @Version: 1.0

*/

public class UserService implements IUserService{

/**

  • login in

  • @param username

  • @param password

*/

@Override

public Boolean login(String username,String password){

System.out.println(“username:”+username);

System.out.println(“password:”+password);

return true;

}

}

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: UserServiceProxy

  • @Author: 流星007

  • @Description: user proxy

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:29

  • @Version: 1.0

*/

public class UserServiceProxy implements IUserService{

private UserService userService;

public UserServiceProxy(UserService userService) {

this.userService = userService;

}

@Override

public Boolean login(String username, String password) {

long startTime = System.currentTimeMillis();

Boolean login = userService.login(username, password);

long endTime = System.currentTimeMillis();

System.out.println(“login time : " + (endTime - startTime) +” ms" );

return login;

}

}

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: Test

  • @Author: 流星007

  • @Description: test

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:15

  • @Version: 1.0

*/

public class Test {

public static void main(String[] args) {

UserServiceProxy userServiceProxy = new UserServiceProxy(new UserService());

Boolean login = userServiceProxy.login(“zhgnsan”, “123456”);

System.out.println("login result : " +login);

}

}

这就是基于组合模式实现的静态代理,代理类和被代理类同时实现一个IUserService接口,代理类中的login方法去调用被代理类中的login方法,这样需要稍微改动一下被代理类,让他们去实现同一个接口。

组合与继承如何选择

========================================================================

静态代理的实现方式相信大家也应该知道怎么实现了,那什么时候实现组合,什么时候使用继承呢?不知道大家有没有听过这么一句话:组合优于继承;能使用组合就少使用继承,原因是继承的层数过大时维护和扩展会非常难受,但是也不绝对,相对于代理模式而言,如果被代理的类来源于第三方,你无法改动原类,那么继承将是一个不错的原则,一般情况下,我还是推荐组合的这种方式。

在这里插入图片描述

动态代理

===============================

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

====================================

静态代理是说完了,还有一种代理模式不知道大家听过没有,那就是动态代理模式,如果熟悉java aop的都应该对java的动态代理不会陌生,那我们现在来讲讲什么是动态代理。

不知道大家思考过一个问题没有,你们觉得静态代理有什么缺点吗?

在这里插入图片描述

可能大家想到了,如果被代理的类过多,成千上百的话,代理类也要成千上百,大大增加了程序员的工作量,他们都是差不多的一个模板,难道就不能只写一次,符合所有的被代理类吗?

当然可以,这个时候动态代理就出现了,动态代理:就是我们不需要在程序运行前为被代理类创建代理类,而是在程序运行中,动态的创建代理类,然后使用这些动态生成的代理类替代原始类,是不是就省去了大量的编码时间?那如何实现呢?

下面请看我表演

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: IUserService

  • @Author: 流星007

  • @Description: user interface

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/29 15:26

  • @Version: 1.0

*/

public interface IUserService {

Boolean login(String username,String password);

}

package com.ymy.proxy;

import org.springframework.cglib.proxy.InvocationHandler;

import org.springframework.cglib.proxy.Proxy;

import java.lang.reflect.Method;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: dynamicUserUserProxy

  • @Author: 流星007

  • @Description: dynamic User proxy

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/30 13:33

  • @Version: 1.0

*/

public class DynamicUserUserProxy {

public Object createProxy(Object object) {

Class[] interfaces = object.getClass().getInterfaces();

DynamicProxyHandler handler = new DynamicProxyHandler(object);

return Proxy.newProxyInstance(object.getClass().getClassLoader(), interfaces, handler);

}

private 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 {

long startTime = System.currentTimeMillis();

Object result = method.invoke(object, args);

long endTime = System.currentTimeMillis();

System.out.println(“login time : " + (endTime - startTime) +” ms" );

return result;

}

}

}

package com.ymy.proxy;

/**

  • @ProjectName: demo

  • @Package: com.ymy.proxy

  • @ClassName: DynamicTest

  • @Author: 流星007

  • @Description: Dynamic Test

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/8/30 13:36

  • @Version: 1.0

*/

public class DynamicTest {

public static void main(String[] args) {

DynamicUserUserProxy proxy = new DynamicUserUserProxy();

IUserService userService = (IUserService) proxy.createProxy(new UserService());

Boolean login = userService.login(“zhangsan”, “123456”);

System.out.println(“login result :” +login);

}

}

username:zhangsan

password:123456

login time : 0 ms

login result :true

Process finished with exit code 0

我这里实现动态代理是基于cglib,由静态代理改成动态代理之后是不是觉得干净多了,如果后续还有类需要代理,就不需要在创建代理类了,让程序在运行中自己创建,简直不要太爽。

代理模式应用场景

=======================================================================

1.日志、鉴权、限流、统计等物业功能的开发。

2.rpc远程调用。

3.一个类需要做扩展功能的时候。

总结

=================================================================

什么是代理模式?,就是在不改变原类的情况下新增新的功能,比如日志、流量监控、请求耗时等等操作都可以通过代理模式来解决。

代理模式分为静态代理和动态代理,静态代理可以通过继承和组合实现,动态代理可以通过cglib和jdk自带的动态代理实现,如果在日常开发过程中,你想要做一些扩展功能,比如:日志、鉴权等,那么就可以考虑一下代理模式哦。

在这里插入图片描述

推荐文章:

【设计模式】单例模式

共150讲,时长共 33小时18分钟 1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。 2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等 3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧 课程内容和目标 本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式 1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值