您现在的位置是:首页 >技术交流 >设计模式之代理模式网站首页技术交流
设计模式之代理模式
简介设计模式之代理模式
代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问。
因为代理类与服务类实现同样的接口,所以代理类能代替服务类提供给客户端。当客户端使用代理类时,代理类能对请求进行处理(例如增加访问控制、缓存请求结果、隐藏对服务类的网络请求、日志记录等),并将请求转发给服务类来处理。
该模式存在 3 类角色:
- 服务接口:定义被代理的服务类接口
- 服务类:提供实际的逻辑
- 代理:持有服务类的引用,能对请求进行访问控制,并将请求转发给服务类进行处理
在 Java 存在两种代理的实现方法,一种是静态代理,通过继承或组合的方式实现;另一种是动态代理,使用反射的方式实现。
静态代理方式的代码实现为:
//服务接口
public interface IGame {
void play();
}
//被代理对象
public class Game implements IGame{
@Override
public void play() {
System.out.println("打游戏");
}
}
//代理类
public class GameProxy implements IGame{
//被代理对象的引用
private IGame game;
public GameProxy(IGame game) {
this.game = game;
}
@Override
public void play() {
//在被代理方法前后增加自定义操作
System.out.println("打游戏之前");
game.play();
System.out.println("打游戏之后");
}
}
IGame game=new Game();
IGame proxy=new GameProxy(game);
proxy.play();
//运行结果
//打游戏之前
//打游戏
//打游戏之后
动态代理又分为 JDK 动态代理和 CGLIB 动态代理,JDK 动态代理通过 JDK 提供的 InvocationHandler
类和 Proxy
类实现, CGLIB 动态代理则是通过第三方字节码生成库。因为本文主要是介绍代理模式,关键还是在于模式的实现思路,反射只是 Java 提供的语法功能,所以这里只是稍微介绍一下 JDK 动态代理的实现代码:
//实现InvocationHandler接口
public class GameProxy2 implements InvocationHandler {
//被代理对象的引用
private Object obj;
public GameProxy2(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("打游戏之前");
//调用被代理对象的方法
Object result = method.invoke(obj, args);
System.out.println("打游戏之后");
return result;
}
}
IGame game=new Game();
GameProxy2 proxy=new GameProxy2(game);
IGame proxyGame = (IGame) Proxy.newProxyInstance(game.getClass().getClassLoader(), game.getClass().getInterfaces(), proxy);
proxyGame.play();
代理模式的优点:在不需要修改服务类的基础上,对服务类进行访问控制。
缺点:使得代码复杂化。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。