代理设计模式(结构型)

思考问题:别人面向UserDao接口写好的类(UserDaoImpl)(你不得修改别人代码),你需要对这个类的方法记录日志或检查权限以确定其他调用者是否有权限使用该方法时你该怎么设计?(或记录调用日志)


解答:自己设计一个日志类(UserDaoLogProxy),将UserDao组合进去(就是UserDaoLogProxy添加一个UserDao属性),然后添加与UserDao类的方法名相同的所有方法,在每个方法中添加权限检查或日志信息后再调用UserDao的相同的方法。这样暴露给其他调用者的UserDaoLogProxy类就是已经实现了日志检查的类了,其他调用者就可以通过UserDao u = new UserDaoLogProxy()来使用到你实现的日志功能或权限功能了。这就是代理模式;
这里写图片描述


实例:
UserDao接口:

package com.shusheng.proxy;
/**访问数据库的dao层*/
public interface UserDao {
    //添加用户
    public boolean insert(User user);
}

UserDaoImpl类:

package com.shusheng.proxy;
/**假设这是时别人已经实现好的类*/
public class UserDaoImpl implements UserDao{

    /**将用户插入到数据库*/
    @Override
    public boolean insert(User user) {
        System.out.println("将user 插入到数据库中");
        return true;
    }
}

代理类:

package com.shusheng.proxy;
/**假设这是实现了记录日志的userDao代理类*/
public class UserDaoLogProxy implements UserDao{

    UserDao userDao;
    //构造代理类时需要传入被代理的对象
    public UserDaoLogProxy(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public boolean insert(User user) {
        this.log();//记录日志
        return userDao.insert(user);
    }

    private void log() {
        System.out.println("记录日志");
    }
}

测试类(模拟上层调用者):

package com.shusheng.proxy;
/**这个类可以模拟调用UserDao类的service类*/
public class ProxyTest {

    public static void main(String[] args) {
        UserDao userDao = new UserDaoImpl();//未使用代理,无法记录日志
        System.out.println(userDao.insert(new User())+"\n");

        userDao = new UserDaoLogProxy(userDao);//代理类记录日志
        System.out.println(userDao.insert(new User()));
    }
}

(实现权限检查同理。)


动态代理与静态代理的区别:
上面这种实现方式称为静态代理,该代理只能代理UserDaoImpl类,但是类似spring框架中不可能为每一个类添加静态代理(会导致类大爆炸的),所以就有了动态代理的概念Proxy,我们把被代理的类传入到Proxy类的方法中,就可以返回一个被代理的对象,而且代理对象实现的业务还可以自己规定(在InvocationHandler中实现)。比如实现权限检查等,动态代理模式在我博客中也有单独介绍,欢迎探讨。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值