二十三种设计模式之代理模式
今天阅读了《设计模式的艺术》这本书,这本书写的很好,详略得当,我很喜欢,今天重点看了二十三设计模式之代理模式。
我相信无论大家学习哪个技术最先考虑的就是下面这两个问题,而在这儿里我也是。
1.什么是代理模式?
2.代理模式能够干什么?
1.1 什么是代理模式?
在这本书中,给出了这样一个概念。
代理模式: 给某一个对象提供一个代理,并由代理对象控制对元对象的引用。(代理模式是一种对象结构型模式)。
这样说其实还不是很好理解,简单的来说,代理模式其实就相当于代购公司,你想买一个东西,这个东西在你在的地方买不到,而你把这个钱交给代购公司让代购公司帮你购买。
2.1 结构图
代理模式的结构很简单,核心是代理类!代理模式当中一共有三个角色,分别是真实角色,代理角色,抽象角色。
类似的结构图如图
2.2 简单代理类伪代码
Class 代理类 extend 抽象类{
private 真实类 object = new 真实类();
public void 请求方法前执行方法(){
具体业务实现…………
}
public void 请求方法(){
请求方法前执行方法();
object.真实请求方法实现();
请求方法后执行方法();
}
public void 请求方法后执行方法(){
具体业务实现…………
}
}
这仅仅只是一个简单的伪代码实现,与真实开发有很大差别!
而真正的代理模式根据业务目的分为不同的种类!
2.3常用的代理模式
-
远程代理
为一个位于不同的地址空间的对象提供一个本地的代理对象。 这个不同的地址空间可以在同一台主机中,也可以在另一台主机中。 远程代理又可以称为大使。
-
虚拟代理
如果需要创建于给资源消耗较大的对象,先创建一个消耗相对较小的对象来表示 真实的对象只在需要时才会被真正创建
-
保护代理
控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限
-
缓冲代理
为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果
-
智能引用代理
当一个对象被引用时,提供一些额外的操作,列入将对象被调用的次数记录下来!
这里仅仅只是这些常用代理模式的简要说明,一些代理模式的具体实现其实非常复杂!
3.1 Java动态代理
这里实现了一个简单的Java动态代理
//抽象角色
public interface UserDao {
public boolean findUserById(String userId);
}
//真实角色
public class UserDaoImpl implements UserDao{
@Override
public boolean findUserById(String userId) {
if(userId.equals("亚雷啊")){
System.out.println("查询"+userId+"用户的信息成功!");
return true;
}else{
System.out.println("查询"+userId+"用户的信息失败!");
return false;
}
}
}
//自定义请求处理程序
public class LogHandler implements InvocationHandler{
private Object object;
//定义无参构造
public LogHandler() {
}
//定义有参构造
public LogHandler(Object object) {
this.object = object;
}
//实现invoke()方法,
//这里的逻辑为before() -> 真实方法 -> after()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object res = method.invoke(object, args);
after();
return res;
}
public void before(){
System.out.println("——————————before()方法执行——————————");
}
public void after(){
System.out.println("——————————after()方法执行——————————");
}
}
//客户类
public class Client {
public static void main(String[] args) {
InvocationHandler invocationHandler = null;
UserDao userDao = new UserDaoImpl();
invocationHandler = new LogHandler(userDao);
UserDao proxy = null;
//通过动态代理创建一个代理对象,用于代理UserDao类型的真实角色
proxy = (UserDao) Proxy.newProxyInstance(
UserDao.class.getClassLoader(),
new Class[]{UserDao.class},
invocationHandler);
proxy.findUserById("亚雷啊");
System.out.println("——————————程序结束了——————————");
}
}
这是程序运行后的结果
/**
* ——————————before()方法执行——————————
* 查询亚雷啊用户的信息成功!
* ——————————after()方法执行——————————
* ——————————程序结束了——————————
*/