欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式之☞代理模式

程序员文章站 2022-03-07 10:10:29
一、代理模式的作用 将主要业务与次要业务进行松耦合的组装 二、代理模式本质 监控行为的特征 例子: 三、生活案例 案例:饭前便后要洗手 分析: 1.分析出主要业务和次要业务 【主要业务】:吃饭,上厕所 【次要业务】:洗手 2. ......

一、代理模式的作用

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

二、代理模式本质

  • 监控行为的特征

例子:

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

三、生活案例

案例:饭前便后要洗手

分析:

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

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

  【次要业务】:洗手

  2.jdk代理模式实现

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

baseservice.java

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

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

person.java

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

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

invaction.java

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

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

proxyfactory.java

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

测试类

testmain.java

 1 import com.chenyanbin.service.baseservice;
 2 import com.chenyanbin.serviceimpl.person;
 3 import com.chenyanbin.util.proxyfactory;
 4 
 5 public class testmain {
 6 
 7     public static void main(string[] args) throws exception {
 8         //mike.eat();
 9 //        person mike=new person();
10         baseservice mike = proxyfactory.build(person.class);
11         mike.eat();
12     }
13 }

吃饭

设计模式之☞代理模式

 

 上厕所

设计模式之☞代理模式

项目目录结构

设计模式之☞代理模式