设计模式(14)代理模式

代理模式简介

代理模式,不好理解,但是代购都是知道的,需要买国内买不到的东西时,就需要找个能买到的代购帮忙买一下。代理模式的思路,类似于代购,当客户端不能访问一些资源或者对象时,可以通过一个代理来间接访问,这种模式就是代理模式。

代理模式在软件设计中广泛应用,而且产生的变种很多,如远程代理、虚拟代理、缓冲代理、保护代理等。

代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

代理模式是一种对象结构型模式,在该模式中引入了一个代理对象,在客户端和目标访问对象之间起到中介的作用。代理对象可以屏蔽或删除客户不想访问的内容和服务,也可以根据客户需求增加新的内容和服务。

代理模式结构

在这里插入图片描述
代理模式的关键是代理类(Proxy)。代理模式中引入了抽象层,客户端针对抽象层编程,这样使得客户端可以一致对待真实对象和代理对象。

  • 抽象主题角色(Subject):声明了代理主题角色和真实主题角色共同的一些接口,因此在任何可以使用真实主题对象的地方都可以使用代理主题角色(想一想代购是不是也是这样?),客户端通常针对抽象主题编程;
  • 代理主题角色(Proxy):代理主题角色通过关联关系引用真实主题角色,因此可以控制和操纵真实主题对象;代理主题角色中提供一个与真实主题角色相同的接口(以在需要时代替真实主题角色),同时还可以在调用对真实主题对象的操作之前或之后增加新的服务和功能;
  • 真实主题角色(RealSubject):真实主题角色是代理角色所代表的真实对象,提供真正的业务操作,客户端可以通过代理主题角色间接地调用真实主题角色中定义的操作。

在实际开发过程中,代理模式产生了很多类型:

  • 远程代理(Remote Proxy):为一个位于不同地址空间的对象提供一个本地的代理对象。不同的地址空间可以在相同或不同的主机中。
  • 虚拟代理(Virtual Proxy):当创建一个对象需要消耗大量资源时,可以先创建一个消耗较少资源的虚拟代理来表示,当真正需要时再创建。
  • 保护代理(Protect Proxy):给不同的用户提供不同的对象访问权限。
  • 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时存储空间,以使更多用户可以共享这些结果。
    智能引用代理(Smart Reference Proxy):当一个对象被引用时提供一些额外的操作,比如将对象被调用的次数记录下来等。

代理模式代码实例

ProxyPattern.cpp

#include <mutex>
#include <time.h>

using namespace std;

// 抽象主题角色
class Subject
{
    
    
public:
  Subject() {
    
    }
  virtual void method() = 0;
};

// 真实主题角色
class RealSubject : public Subject
{
    
    
public:
  RealSubject() {
    
    }

  void method()
  {
    
    
    cout << "调用业务方法" << endl;
  }
};

// Log类
class Log
{
    
    
public:
  Log() {
    
    }

  string getTime()
  {
    
    
    time_t t = time(NULL);
    char ch[64] = {
    
    0};
    //年-月-日 时:分:秒
    strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", localtime(&t));
    return ch;
  }
};

// 代理类
class Proxy : public Subject
{
    
    
public:
  Proxy()
  {
    
    
    realSubject = new RealSubject();
    log = new Log();
  }

  void preCallMethod()
  {
    
    
    cout << "方法method()被调用,调用时间为" <<  log->getTime().c_str() << endl;
  }

  void method()
  {
    
    
    preCallMethod();
    realSubject->method();
    postCallMethod();
  }

  void postCallMethod()
  {
    
    
    cout << "方法method()调用调用成功!" << endl;
  }

private:
  RealSubject *realSubject;
  Log *log;
};

ProxyPattern.h

#include <iostream>
#include "ProxyPattern.h"

int main()
{
    
    
  Subject *subject;
  subject = new Proxy();
  subject->method();

  delete subject;

  return 0;
}

代理模式总结

优点:

  • 代理模式能够协调调用者和被调用者,降低系统耦合度;
  • 客户端针对抽象主题角色编程,如果要增加或替换代理类,无需修改源代码,符合开闭原则,系统扩展性好;
  • 远程代理优点:为两个位于不同地址空间的对象的访问提供解决方案,可以将一些资源消耗较多的对象移至性能较好的计算机上,提高系统整体性能;
  • 虚拟代理优点:通过一个资源消耗较少的对象来代表一个消耗资源较多的对象,节省系统运行开销;
  • 缓冲代理优点:为某一个操作结果提供临时的存储空间,可以在后续操作中使用这些结果,缩短了执行时间;
  • 保护代理优点::控制对一个对象的访问权限,为不同客户提供不同的访问权限。

缺点:

  • 增加了代理类和代理对象,增加了代理对象中的某些处理流程,可能会使得系统响应变慢;
  • 有的代理模式(如远程代理)实现代码较为复杂。

适用环境:

  • 当客户端对象需要访问远程主机中的对象——可以使用远程代理;
  • 当需要用一个资源消耗较少的对象来代表一个资源消耗较多的对象——虚拟代理;
  • 当需要限制不同用户对一个独享的访问权限——保护代理;
  • 当需要为一个频繁访问的操作结果提供临时存储空间——缓冲代理;
  • 当需要为一个对象的访问提供一些额外的操作——智能引用代理。

おすすめ

転載: blog.csdn.net/qq_24649627/article/details/115380311