23种设计模式之代理模式

Bella ·
更新时间:2024-09-21
· 926 次阅读

代理模式 为什么要学习代理模式? 这是SpringAOP的底层 代理模式的分类: 静态代理 动态代理 在这里插入图片描述 静态代理: 角色分析: 抽象角色:一般会使用接口或者抽象类来解决 真实角色:被代理的角色 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作 客户:访问代理对象的人。 示例:

一般情况:

租房接口:

//租房 public interface Rent { public void rent(); } 房东类: //房东 public class Host implements Rent { @Override public void rent() { System.out.println("房东出租房子"); } }

顾客类:

public class Client { public static void main(String[] args) { Host host = new Host(); host.rent(); } }

出现了代理角色:

public class Proxy implements Rent{ private Host host;//组合 public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent(){ host.rent(); } }

则顾客可以通过代理租房:

public class Client { public static void main(String[] args) { Host host = new Host(); //代理 Proxy proxy = new Proxy(host); proxy.rent(); } }

代理角色可以有一些自己的附属操作,属于自己的功能,,否则代理没有意义:

public class Proxy implements Rent{ private Host host;//组合 public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent(){ seeHouse(); hetong(); fare(); host.rent(); } //代理的附属操作 //看房 public void seeHouse(){ System.out.println("中介带你看房"); } //收中介费 public void fare(){ System.out.println("收中介费"); } //签合同 public void hetong(){ System.out.println("签合同"); } }

代理模式的好处:

可以使真实角色的操作更加纯粹,不用关注一些公共的业务。 公共业务就交给代理角色。实现了业务的分工。 公共业务发生扩展的时候,方面集中管理。

缺点:

一个真实角色就会产生一个代理对象,代码量会翻倍,开发效率低。 静态代理再理解:

根据实际业务模拟:

UserService:

public interface UserService { public void add(); public void delete(); public void update(); public void query(); }

UserServiceImpl:

public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("增加用户"); } @Override public void delete() { System.out.println("删除用户"); } @Override public void update() { System.out.println("更新用户"); } @Override public void query() { System.out.println("查询用户"); } }

此时若需要增加日志功能,则需要在每个实现类的实现方法中,增加日志输出。若有n个实现类,则需要改n*n此,特别麻烦。

例如:

public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("调用了add方法"); System.out.println("增加用户"); } @Override public void delete() { System.out.println("调用了delete方法"); System.out.println("删除用户"); } @Override public void update() { System.out.println("调用了update方法"); System.out.println("更新用户"); } @Override public void query() { System.out.println("调用了query方法"); System.out.println("查询用户"); } }

违背开闭原则!!!

故引入代理:

public class UserServiceProxy implements UserService{ private UserServiceImpl userServiceImpl; public UserServiceProxy(UserServiceImpl userServiceImpl) { this.userServiceImpl = userServiceImpl; } @Override public void add() { printLog(); userServiceImpl.add(); } @Override public void delete() { printLog(); userServiceImpl.delete(); } @Override public void update() { printLog(); userServiceImpl.update(); } @Override public void query() { printLog(); userServiceImpl.query(); } public void printLog(){ System.out.println("打印日志"); } }

改变原来代码是大忌!!!

AOP的理解:

在这里插入图片描述

动态代理: 动态代理和静态代理一样 动态代理的代理类是动态生成的,不是我们直接写好的。 动态代理分为两大类:基于接口的动态代理,基于类的动态代理 基于接口—jdk动态代理 基于类—cglib java字节码实现:javasist 基于接口的动态代理:

需要了解两个类:Proxy:代理,InvocationHandler

InvocationHandler java.lang.reflect包下 是由代理实例的,调用处理程序实现的接口。每个代理实例都有一个关联的调用处理程序。当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。 invoke方法是通过反射的方式执行方法。

创建动态的代理类:

//自动生成代理类的类 public class ProxyInvocationHandler implements InvocationHandler{ //被代理的接口 private Rent rent; public void setRent(Rent rent){ this.rent=rent; } //生成得到代理对象 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } //处理代理实例并返回结果 //代理实例:被代理的人 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(rent, args); return result; } }

此时顾客:

public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理 ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(); proxyInvocationHandler.setRent(host); Rent proxy = (Rent) proxyInvocationHandler.getProxy(); proxy.rent(); } }

若需要代理类需要扩展功能:

//自动生成代理类的类 public class ProxyInvocationHandler implements InvocationHandler{ //被代理的接口 private Rent rent; public void setRent(Rent rent){ this.rent=rent; } //生成得到代理对象 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } //处理代理实例并返回结果 //代理实例:被代理的人 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); fare(); hetong(); Object result = method.invoke(rent, args); return result; } //看房 public void seeHouse(){ System.out.println("中介带你看房"); } //收中介费 public void fare(){ System.out.println("收中介费"); } //签合同 public void hetong(){ System.out.println("签合同"); } }

形成通用的动态代理模板:

//自动生成代理类的类 public class ProxyInvocationHandler implements InvocationHandler{ //被代理的接口 private Object object; public void setObject(Object object){ this.object=object; } //生成得到代理对象 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(),this); } //处理代理实例并返回结果 //代理实例:被代理的人 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(object, args); return result; } }

动态代理的好处:

可以使真实角色的操作更加纯粹,不用关注一些公共的业务。 公共业务就交给代理角色。实现了业务的分工。 公共业务发生扩展的时候,方面集中管理。 一个动态代理类代表的是一个接口,一般就是对应的一类业务。 一个动态代理类可以代理多个类,只要是实现了同一个接口即可。
作者:纪伯伦的小弟



代理 23种设计模式 设计模式 代理模式

需要 登录 后方可回复, 如果你还没有账号请 注册新账号