经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式之?代理模式
来源:cnblogs  作者:陈彦斌  时间:2019/10/15 8:59:02  对本文有异议

一、代理模式的作用

  • 将主要业务与次要业务进行松耦合的组装

二、代理模式本质

  • 监控行为的特征

例子:

  <input type="button" onclick="处理函数">

三、生活案例

案例:饭前便后要洗手

分析:

  1.分析出主要业务和次要业务

  【主要业务】:吃饭,上厕所

  【次要业务】:洗手

  2.JDK代理模式实现

    2.1、接口角色:定义所有需要被监听行为

BaseService.java

  1. 1 package com.chenyanbin.service;
  2. 2
  3. 3 /*
  4. 4 * 只有需要被监控的行为才有资格在这里声明
  5. 5 */
  6. 6 public interface BaseService {
  7. 7 public void Eat();
  8. 8 public void Wc();
  9. 9 }

    2.2、接口实现类:中国人、印度人

Person.java

  1. 1 package com.chenyanbin.serviceImpl;
  2. 2
  3. 3 import com.chenyanbin.service.BaseService;
  4. 4
  5. 5 public class Person implements BaseService {
  6. 6
  7. 7 @Override
  8. 8 public void Eat() { //主要业务,代理模式要求开发任务只关心主要业务
  9. 9 System.out.println("使用筷子吃饭");
  10. 10 }
  11. 11
  12. 12 @Override
  13. 13 public void Wc() {
  14. 14 System.out.println("测试地球重力是否存在");
  15. 15 }
  16. 16 }

    2.3、通知类:1)次要业务进行具体实现    2)通知JVM,当前被拦截的主要业务方法与次要业务方法应该如何绑定执行

Invaction.java

  1. 1 package com.chenyanbin.util;
  2. 2
  3. 3 import java.lang.reflect.InvocationHandler;
  4. 4 import java.lang.reflect.Method;
  5. 5
  6. 6 import com.chenyanbin.service.BaseService;
  7. 7
  8. 8 public class Invaction implements InvocationHandler {
  9. 9 private BaseService obj;// 具体被监控对象
  10. 10
  11. 11 public Invaction(BaseService param) {
  12. 12 this.obj = param;
  13. 13 }
  14. 14
  15. 15 /*
  16. 16 * invoke方法:被监控行为将要执行时,会被JVM拦截,被监控行为和行为实现方会被作为参数输送到invoke
  17. 17 * ***通知JVM,这个被拦截方法是如何与当前次要业务方法绑定实现 invoke方法三个参数 小明.Eat();//JVM拦截
  18. 18 * Eat方法封装为Method类型方法 Eat方法运行时所有的实参封装到Object[] 将负责监控小明的代理对象作为invoke方法第一个参数
  19. 19 *
  20. 20 */
  21. 21 @Override
  22. 22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23. 23 // 0.局部变量,接受主要业务方法执行完毕后返回值
  24. 24 Object value;
  25. 25 // 1.确认当前被拦截行为
  26. 26 String methodName = method.getName();
  27. 27 // 2.根据被拦截行为不同,决定主要业务和次要业务如何绑定执行
  28. 28 if ("Eat".equals(methodName)) { // 饭前要洗手
  29. 29 Wash();// 洗手
  30. 30 value = method.invoke(this.obj, args);// 当前主要业务
  31. 31 } else { // 便后洗手
  32. 32 value = method.invoke(this.obj, args);// 当前主要业务
  33. 33 Wash();// 洗手
  34. 34 }
  35. 35 return value; //返回被拦截方法
  36. 36 }
  37. 37
  38. 38 // 次要业务
  39. 39 public void Wash() {
  40. 40 System.out.println("--------洗手--------");
  41. 41 }
  42. 42 }

    2.4、监控对象(代理对象):1)被监控实例对象   2)需要被监控行为   3)具体通知类实例对象

ProxyFactory.java

  1. 1 package com.chenyanbin.util;
  2. 2
  3. 3 import java.lang.reflect.InvocationHandler;
  4. 4 import java.lang.reflect.Proxy;
  5. 5
  6. 6 import com.chenyanbin.service.BaseService;
  7. 7
  8. 8 public class ProxyFactory {
  9. 9 /*
  10. 10 * JDK动态代理模式下,代理对象的数据类型 应该由监控行为来描述 参数:Class文件,监控类
  11. 11 */
  12. 12 public static BaseService build(Class classFile) throws Exception {
  13. 13 //1.创建被监控实例对象
  14. 14 BaseService obj = (BaseService) classFile.getDeclaredConstructor().newInstance();
  15. 15 //2.创建通知对象
  16. 16 InvocationHandler adviser=new Invaction(obj);
  17. 17 //3.向JVM申请负责监控obj对象指定行为的监控对象(代理对象)
  18. 18 /*
  19. 19 * loader:被监控对象隶属的类文件在内存中真实地址
  20. 20 * interfaces:被监控对象隶属的类文件实现接口
  21. 21 * h:监控对象发现小明要执行被监控行为,应该由哪一个通知对象进行辅助
  22. 22 */
  23. 23 BaseService $proxy=(BaseService)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser);
  24. 24 return $proxy;
  25. 25 }
  26. 26 }

测试类

TestMain.java

  1. 1 import com.chenyanbin.service.BaseService;
  2. 2 import com.chenyanbin.serviceImpl.Person;
  3. 3 import com.chenyanbin.util.ProxyFactory;
  4. 4
  5. 5 public class TestMain {
  6. 6
  7. 7 public static void main(String[] args) throws Exception {
  8. 8 //mike.Eat();
  9. 9 // Person mike=new Person();
  10. 10 BaseService mike = ProxyFactory.build(Person.class);
  11. 11 mike.Eat();
  12. 12 }
  13. 13 }

吃饭

 

 上厕所

项目目录结构

 

原文链接:http://www.cnblogs.com/chenyanbin/p/11674422.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号