zl程序教程

您现在的位置是:首页 >  云平台

当前栏目

设计模式之代理模式

2023-09-11 14:22:29 时间

1. 概述

应用程序开发人员在进行软件设计的时候会出于对安全性和性能等的考虑,不会让用户可以直接操作对象本身,而是通过在客户端和对象之间加一层代理层实现的,这样的设计模式就是这篇文章要讲的:代理模式。

定义

代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的访问

目的

提供其它对象一个代理,来控制该对象的访问权限、控制来延迟对象的创建和实例化。

结构

2. 编码

这里是代理模式的模型代码,通过一个代理传达一个请求。

#pragma once

#include <iostream>
#include <string>

using std::cout;
using std::endl;

//基类
template<typename T> class BaseSubject
{
public:
    BaseSubject(){}
    ~BaseSubject(){}

public:
    virtual void request()=0;
};

//派生出来的实体类
template<typename T> class Subject: public BaseSubject<T>
{
public:
    Subject(T var):m_var(var)
    {
    }
    ~Subject();

private:
    T m_var;    //变量

public:
    void request() override
    {
        cout << "subject request..., var: " << this->m_var << endl;
    }
};

//派生出来的代理类
template<typename T> class Proxy: public BaseSubject<T>
{
public:
    Proxy(T var):m_var(var)
    {
        this->m_subject = nullptr;
    }
    ~Proxy()
    {
        if(nullptr != this->m_subject)
        {
            delete this->m_subject;
            this->m_subject = nullptr;
        }
    }

private:
    T m_var;    //变量
    Subject<T>* m_subject;

public:
    void request() override
    {
        if(nullptr == this->m_subject)
        {
            this->m_subject = new Subject<T>(this->m_var);
        }
        this->m_subject->request();  //代理调用实例对象的方法
    }
};
调用:

    Proxy<std::string>* proxy = new Proxy<std::string>("hello keke");
    proxy->request();

3. 总结

代理模式的应用场景:
(1)远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。例如,为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担了大部份的网络通讯工作。由于客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。
(2)虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真是对象。这样可以达到性能的最优化,比如打开一个很大的HTML网页时,里面可能有很多文字和图片,但还是可以很快打开它,此时看到的是所有的文字,但是图片却是一张张下载下来的。对于那些未打开的图片框,就是通过虚拟代理来替代了真实的图片,此时代理存储了真实图片的路径和尺寸。
(3)安全代理,用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候。
(4)智能指引,是指当调用真实的对象时,代理处理另外一些事。例如计算机真实对象的引用次数,这样当对象没有引用时,可以自动释放它;或者当第一次引用一个持久对象时,将它装入内存中;或者在访问一个实际对象前,检查是否已经锁定它,以确保其它对象不能改变它。它们都是通过代理模式在访问一个对象时附加一些内务处理。
(5)Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。


代理模式(Proxy)VS 装饰者(Decorator)
意图:它们都提供间接访问对象层,都保存被调用对象的引用。
代理模式(Proxy):为另一个对象提供一个替身或占位符以控制对这个对象的访问,简而言之就是用一个对象来代表另一个对象。
装饰者(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式比生成子类更为灵活,它避免了类爆炸问题,像装饰者(Decorator),代理模式(Proxy)组成一个对象并提供相同的接口,但代理模式并不关心对象动态职能的增减。
在代理模式(Proxy)中Subject定义了主要的功能,而且Proxy根据Subject提供功能控制对象的访问权限。在装饰者(Decorator)中Component只是提供了其中的一些功能,需要通过装饰链动态给对象增加职能。