设计模式之☞代理模式
一、代理模式的作用
- 将主要业务与次要业务进行松耦合的组装
二、代理模式本质
- 监控行为的特征
例子:
<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 }
吃饭

上厕所

项目目录结构

赞 (0)
