跳到主要内容

二十三种设计模式之代理模式

今天阅读了《设计模式的艺术》这本书,这本书写的很好,详略得当,我很喜欢,今天重点看了二十三设计模式之代理模式。

我相信无论大家学习哪个技术最先考虑的就是下面这两个问题,而在这儿里我也是。

1.什么是代理模式?

2.代理模式能够干什么?


1.1 什么是代理模式?

在这本书中,给出了这样一个概念。 代理模式: 给某一个对象提供一个代理,并由代理对象控制对元对象的引用。(代理模式是一种对象结构型模式)。 这样说其实还不是很好理解,简单的来说,代理模式其实就相当于代购公司,你想买一个东西,这个东西在你在的地方买不到,而你把这个钱交给代购公司让代购公司帮你购买。

2.1 结构图

代理模式的结构很简单,核心是代理类!代理模式当中一共有三个角色,分别是真实角色,代理角色,抽象角色。

类似的结构图如图

代理模式.png

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()方法执行——————————
* ——————————程序结束了——————————
*/