
最易懂设计模式解析
适配器设计模式
模板方法设计模式
Mybatis多级代理
1. 认识代理模式
1.1 模式定义
给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。
代理模式是一种对象结构型模式。在代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到中介的作用,它去掉客户不能看到的内容和服务或者增添客户需要的额外的新服务。
1.2 解决何种问题
将【次要业务】和【主要业务解耦合】。
核心就是代理对象(Proxy)。
1.3次要业务和主要业务
1.3.1 它们之间的区分
次要业务:辅助【主要业务】顺利实现。在项目中【次要业务】往往大量重复出现。
主要业务:主要任务。
1.3.2 次要业务对于开发效率影响
- 加载驱动类。【次要业务】
- 建立连接通道。【次要业务】
- 建立数据库操作对象。【次要业务】
- 推送sql命令道数据库执行并返回处理结果。【主要业务】
- 销毁connection,statement,resultSet。【次要业务】
1.4 代理模式的本质
控制对象访问(行为的监听)
<input type="button" onclick="fun1">
onclick行为监听对象(代理对象proxy)对 button 单击的行为调用了fun1方法(InvovationHandler)
1.5 代理模式的组成
- 接口:声明需要被监听行为。
- 代理实现类:次要业务实现、将次要业务和主要业务绑定执行。
- 代理对象(监听对象)
2. 实例讲解
2.1 实例业务介绍
饭前便后要洗手
【主要业务】:吃饭、便便。
【次要业务】:洗手。
2.2 具体实现
创建一个接口BaseService
//被监控的行为
public interface BaseService {
//吃饭方法
public void eating(String food);
//上厕所方法
public void wcing();
}
代理实现类Agent
public class Agent implements InvocationHandler {
private BaseService obj;// 被开发人员索要的真实对象
//完成次要业务和主要业务绑定
public Agent(BaseService param) {
this.obj = param;
}
/*
* Object proxy:本次负责监听对象----onclick
*
* Method method: 被拦截的主要业务方法
*
* Object[] params:被拦截的主要业务方法接受的实参
*/
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
//1.读取被拦截的方法名称
String methodName = method.getName();
if("eating".equals(methodName)){//饭前要洗手
wash();
method.invoke(obj, params);
}else{//便后要洗手
method.invoke(obj, params);
wash();
}
return null;
}
//次要业务
private void wash(){
System.out.println("洗手");//解耦合;
}
创建接口实现类,Person实现了BaseService中的方法是需要被监听的方法
public class Person implements BaseService {
@Override
public void eating(String food) {
System.out.println("狼吞虎咽吃 "+food);
}
@Override
public void wcing() {
System.out.println("减体重...");
}
}
创建一个代理工厂ProxyFactory
public class ProxyFactory {
//扮演一个角色(吃和拉的监听对象)
public static BaseService newInstance(Class classFile) throws InstantiationException, IllegalAccessException{
//0.创建被索要的类型的实例对象
BaseService 小明 = new Person();
//1.拥有一个代理实现类对象
InvocationHandler agent = new Agent(小明);//小明被囚禁到了Agent中
//2.申请/注册一个对特定行为进行监控对象(代理对象)
/*
* loader:指向被监控的类文件在内存中真实地址
* interfaces(classArray): 被监控的类所实现的接口,这个接口中声明的方法,就是需要被监控行为也是主要业务行为名称
*/
Class classArray[]={BaseService.class}; //这个接口里所有的方法都要被监听
//创建一个代理监听对象
BaseService 监听对象=(BaseService) Proxy.newProxyInstance(Person.class.getClassLoader(), classArray, agent);
return 监听对象; //返回的是一个假货(披着羊皮的狼) 监听对象
}
测试类
public class TestMain {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
//BaseService 小明 = new Person();//丑陋的行为 不受监控的对象
BaseService 小明 = ProxyFactory.newInstance();
小明.eating("鸡");
}
}
测试结果
洗手
狼吞虎咽吃 鸡
网友评论