代理模式

本模式并没有在实际工作中碰到使用场景,就是单纯的要把定的基本目标:基本的设计模式写完。我在参考别人写的时候,看到有一句话说的很好:设计模式不需要刻意使用,但是需要刻意练习

定义

为其他对象提供一种代理以控制对这个对象的访问(不改变原始类代码的情况下,通过引入代理类来给原始类附加功能)。简单理解,就比如说我想访问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)

参考

代理模式

《大话设计模式》

设计模式之美

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值