本模式并没有在实际工作中碰到使用场景,就是单纯的要把定的基本目标:基本的设计模式写完。我在参考别人写的时候,看到有一句话说的很好:设计模式不需要刻意使用,但是需要刻意练习。
定义
为其他对象提供一种代理以控制对这个对象的访问(不改变原始类代码的情况下,通过引入代理类来给原始类附加功能)。简单理解,就比如说我想访问Google,那么会用到 VPN,那么这个 VPN 就是一个代理,而真正访问的是我。
实战
基于接口实现
普通类和代理类都实现一个接口,普通类只做业务相关的代码逻辑,代理类会做其余的事情
public interface IUserController {
void login();
void register();
}
public class UserControllerProxy implements IUserController {
private UserController userController;
public UserControllerProxy(UserController userController) {
this.userController = userController;
}
@Override
public void login() {
/**
* 可以有其他额外的操作,比如日志啥的
*/
System.out.println("代理登录");
userController.login();
}
@Override
public void register() {
System.out.println("代理注册");
userController.register();
}
}
public class UserController implements IUserController{
@Override
public void login() {
System.out.println("登录逻辑");
}
@Override
public void register() {
System.out.println("注册逻辑");
}
}
//调用
IUserController userController = new UserControllerProxy(new UserController());
userController.login();
userController.register();
基于继承实现
当原始类没有定义接口,并且原始类代码并不是我们开发,我们无法直接修改原始类,给它重新定义一个接口。这种,我们一般就使用继承的方式,让代理类继承原始类,然后扩展附加功能。
public class UserController1 {
public void login() {
System.out.println("登录逻辑");
}
public void register() {
System.out.println("注册逻辑");
}
}
public class UserControllerProxy1 extends UserController1 {
public void login() {
super.login();
/**
* 可以有其他额外的操作,比如日志啥的
*/
System.out.println("代理登录");
}
public void register() {
super.register();
System.out.println("代理注册");
}
}
//调用
UserController1 userController1=new UserControllerProxy1();
userController1.register();
userController1.login();
动态代理
类似 Spring AOP 全是用的动态代理,基于反射。
假如有50个要添加附加功能的原始类,那么就需要创建对应的50个代理类,这显然是不能接受的。并且每个代理类都有重复代码。那么使用动态代理解决这个问题:在运行的时候动态的创建原始类对应的代理类,然后再系统中用代理类替换掉原始类。
public class DynamicProxy {
public Object createProxy(Object proxyObject){
Class<?>[] interfaces=proxyObject.getClass().getInterfaces();
DynamicProxyHandler handler = new DynamicProxyHandler(proxyObject);
return Proxy.newProxyInstance(proxyObject.getClass().getClassLoader(), interfaces, handler);
}
private class DynamicProxyHandler implements InvocationHandler{
private Object proxyObject;
public DynamicProxyHandler(Object proxyObject) {
this.proxyObject = proxyObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("逻辑处理");
return null;
}
}
}
public class UserController implements IUserController{
@Override
public void login() {
System.out.println("登录逻辑");
}
@Override
public void register() {
System.out.println("注册逻辑");
}
}
//调用
DynamicProxy proxy = new DynamicProxy();
IUserController userController12 = (IUserController) proxy.createProxy(new UserController());
userController12.register();
userController12.login();
总结
上面的实现方式,相当于代理模式可以分为两种:静态代理和动态代理。
静态代理:实现接口+继承
动态代理:反射(Spring AOP)
参考
《大话设计模式》