美文网首页
设计模式——代理模式

设计模式——代理模式

作者: 东方胖 | 来源:发表于2023-08-19 23:18 被阅读0次

Provide a surrogate or placeholder for annother obeject to control access to it.

代理模式的结构有益于几乎所有的构建类设计模式。
它的 UML 图类似一个三角形

proxy uml 图,使用staruml 绘制
class Grapic
{
public:
    virtual void draw() = 0;
    virtual void save() = 0;
    virtual void load() = 0;
};


class Image: public Grapic
{
public:
    void draw() {
        std::cout << "draw a image self" << std::endl; 
    }

    void save() {
       std::cout << "save on disk" << std::endl;
    }

    void load() {
         std::cout << "load from disk .." << std::endl;
    }

};

class ImageProxy: public Grapic
{
public:
    ImageProxy(const char *imageFile, Context* context) {
        _imageFile = imageFile;
        _image = nullptr;
    }
    void draw() {
          _image->draw();
    }
   void load() {
        if (_context->getUser() == UserRole::Super)
            return _image->load();
       std::cout << "have not access right" << std::endl;
      return;
  }

protected:
   Image* loadImage() {
    if (_image == nullptr) {
         return new Image();
    }
    return _image;
  }
private:
    char * imageFile;
    Image *_image;
};

代理模式有两个典型的特征:

  • 两个子类继承自一个父类,有时候可以是一个接口,这意味着两个子类具有一样的接口(某些virtual函数)
  • 代理类持有一个被代理的引用——这种方法在行为类模式中颇为常见。

因为有第二条,所有代理总是可以通过这个引用操纵真实的对象。

乍看十分别扭的结构,它会在什么场景下有用呢?
因为 ImageProxy 几乎就是 Image的影子,但是它们只是在抽象接口上是一致的,彼此的 constructor 和 属性其实可以大不一样,Proxy可以控制对 被代理对象的访问——做到这一点,只需要在代码中,凡出现要传递 被代理对象的上层client代码中,代之以 Proxy 。

比方说,上面的 Image 的 load 动作,它是一个抽象的接口,
当从代理的 load 入口走进去的时候,先从上下文中获取一些类似角色的参数,校验其访问权限是否满足

这是一种类似权限控制的访问场景。因为 new Image() 的动作完全被代理负责。

  • 第一种情况,对client 隐藏真实的对象,在client 上下文中,类似下面这种的写法
    有一个client context 的上下文长这样
void operate(Graphic* g); 

那么可以可以用代理调用

operate(new ImageProxy()) ; // C++ 注意持有 代理的指针进行内存管理
  • 另一种情况是占位作用,一般如果类似 load() 这种的动作,是一个耗时操作,它返回一个 Image——上面的代码没有体现这点,但我们可以假设它其实是一个有 UI呈现的动作,当 load 发生时,用代理去做,而不是直接在图片中实现,这样代理可以充当一个占位符,先假设它完成了,然后上下文再在合适的时机,调用 draw 之类真实的绘制动作去完成。
    这会引来一中效果,类似网页加载,那些比较清楚的图片,总是比较慢,我们先看到大多数文字,然后一张图片的占位符,类似下面这样。然后过一段时间,这张图真实地加载出来,——我们此时可能已经读完一百多字了。


    占位图
  • 一个真实的应用是 智能指针

智能指针 是 C++为了实现内存自动管理的一种技术——将原始的指针封装在一个有构造函数和析构函数的类中,利用栈对象自动调用析构的特性实现自动化释放内存。

在std::auto_ptr 里可能不太能清晰地看到代理模式的三角结构。但是如果我们把运算符 -> * 看成是一个公共接口的话,auto_ptr 和 裸指针对象都支持该运算,因而可以视为一种公共的接口,这样看来,它们完全符合代理模式的三角接口。

试用伪代码表达如下, -> 用接口 reference 表示,deReference代替 * 运算
于是有一个“看不见”的公共接口,大概定义成这样

template<class T>
class PointerInterface
{
public:
    T* reference() = 0;
    T deReference() = 0;
};

Pointer 具有 reference 和deReference操作。
于是智能指针 SmartPointer 也从PointerInterface 继承,然后持有Pointer 的句柄(引用) 这样,代理的三角结构是不是就很清晰了。
实际的实现中。

很关键的点也正是如此:

  • 智能指针,不管是旧的 auto_ptr 还是新版C++11的 share_ptr unique_ptr 等等都一致的重载了运算符 -> 和 符号,这里不是乘法是指针的解引用运算。
  • 其次持有裸指针的真身,从而实现对它指向的内存的“管理”

相关文章

  • Mybatis代理设计模式(Proxy)与编程实现原理

    最易懂设计模式解析适配器设计模式模板方法设计模式Mybatis多级代理 1. 认识代理模式 1.1 模式定义 给某...

  • 模板方法设计模式(Template Method)

    最易懂设计模式解析适配器设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识模板方法模式 1.1 ...

  • 适配器设计模式(Adapter)

    最易懂设计模式解析模板方法设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识适配器模式 1.1 ...

  • 理解java的代理模式和动态代理

    代理模式 代理模式是23种设计模式之一,属于结构型模式。代理模式是最常见也是最常用的模式之一,只不过有很多设计模式...

  • spring框架中的设计模式二

    在这篇文章中,介绍4种设计模式。结构型设计模式:代理和复合模式。行为型设计模式:策略和模板方法模式。 代理模式 面...

  • 10、结构型模式-代理设计模式

    1、加盟商来啦-你需要掌握的代理设计模式 简介:讲解代理设计模式,让代理帮你完成工作 代理设计模式(Proxy P...

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 动态代理原理解析

    注:源自于Android 一、代理模式 代理模式是java23种设计模式常用的一种设计模式。代理模式是客户端不直接...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

网友评论

      本文标题:设计模式——代理模式

      本文链接:https://www.haomeiwen.com/subject/cbajmdtx.html