新版MQL语言程序设计:代理模式的原理、应用及代码实现

文章目录

一、什么代理模式

代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问。代理对象充当了客户端和目标对象之间的中介,可以在不改变目标对象的情况下,增加额外的功能或控制访问。

二、代理模式的实现原理

  1. 定义一个接口:首先需要定义一个接口,该接口是代理对象和目标对象共同实现的接口。这个接口定义了客户端可以使用的方法。
  2. 创建目标对象:实现接口的目标对象是真正执行业务逻辑的对象。
  3. 创建代理对象:代理对象也实现了接口,并持有一个对目标对象的引用。代理对象在执行方法时,会调用目标对象的相应方法,并可以在调用前后执行一些额外的操作。
  4. 客户端使用代理对象:客户端通过代理对象来访问目标对象,而不是直接访问目标对象。客户端可以像访问目标对象一样使用代理对象,而无需关心代理对象和目标对象之间的具体实现细节。

代理模式的实现可以有多种形式,包括静态代理和动态代理。静态代理是在编译时就已经确定代理对象和目标对象的关系,而动态代理是在运行时动态生成代理对象。

三、代理模式应用场景

  • 远程代理:当对象位于不同的地址空间时,可以使用代理模式来在客户端和远程对象之间建立通信,使得客户端可以透明地访问远程对象。

  • 虚拟代理:当创建一个对象需要很大的开销时,可以使用代理模式来延迟对象的实例化,只有在真正需要时才创建对象。这样可以提高系统的性能和资源利用率。

  • 安全代理:代理模式可以控制对真实对象的访问权限,只有满足特定条件的客户端才能访问真实对象,从而保护真实对象的安全性。

  • 日志记录代理:代理模式可以在调用真实对象的方法前后进行一些额外的操作,比如记录日志、统计方法调用次数等。

  • 缓存代理:代理模式可以为一些昂贵的操作提供缓存,当相同的请求到达时,可以直接返回缓存中的结果,避免重复计算。

  • 延迟加载代理:代理模式可以延迟加载真实对象,只有在真正需要时才加载,从而提高系统的响应速度。

举个例子:假设有一个图片加载器类ImageLoader,它负责从网络上下载图片并显示。为了提高性能,我们可以使用代理模式来实现一个图片加载器的代理类ImageLoaderProxy。当客户端调用ImageLoaderProxy的loadImage方法时,代理类会先检查本地缓存中是否存在该图片,如果存在则直接返回缓存的图片;如果不存在,则调用实际的ImageLoader对象来下载并显示图片,并将下载的图片缓存起来。这样,代理类在不改变原有ImageLoader类的情况下,增加了缓存功能。

四、代理模式的代码实现

cpp 复制代码
//+------------------------------------------------------------------+
//|                                                        Proxy.mqh |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| interface --- for patterns                                         |
//+------------------------------------------------------------------+
interface ClientInterface //pattern client
{
    string Output(void); //returns header
    void Run(void); //execute the pattern client
};
//+------------------------------------------------------------------+
//| interface --- for patterns                                         |
//+------------------------------------------------------------------+
void Run(ClientInterface* client) //launches a pattern
{
    printf("---\n%s",client.Output()); //print pattern header
    client.Run(); //execute client collaborations
    delete client; //exit
}
//+------------------------------------------------------------------+
//| structure                                                        |
//+------------------------------------------------------------------+
//      |Client|-------------------------->| Subject |
//                                         |---------|
//                                         |Request()|
//                                         |...      |
//                                              ^
//                                              |
//         +------------------------------------+------------...
//         |           real_subject             |
//   |RealSubject|<-----------------|         Proxy        |
//   |-----------|                  |----------------------|
//   |Request()  |                  |Request()             |
//   |...        |                  | ...                  |
//                                  | realSubject.Request()|
//                                  | ...                  |
//                                  |...                   |
//+------------------------------------------------------------------+
// 定义真实主体和代理的公共接口
// 以便在任何需要真实主体的地方都可以使用代理
class Subject
{
    public:
        virtual void      Request(void)=0;
};
// 定义代理所代表的真实对象。
class RealSubject:public Subject
{
    public:
        void              Request(void);
};
//
void RealSubject::Request(void)
{
    Print("real subject");
}
//维护一个引用,该引用允许代理访问真实主体
class Proxy:public Subject
{
    protected:
        RealSubject*      real_subject;
    public:
        ~Proxy(void);
        void              Request(void);
};
//
Proxy::~Proxy(void)
{
    delete real_subject;
}
//
void Proxy::Request(void)
{
    if(!CheckPointer(real_subject))
    {
        real_subject=new RealSubject;
    }
    real_subject.Request();
}
//
class Client:public ClientInterface
{
    public:
        string            Output(void);
        void              Run(void);
};
string Client::Output(void)
{
    return __FUNCTION__;
}
//
void Client::Run(void)
{
    Subject* subject=new Proxy;
    subject.Request();
    delete subject;
}
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void OnStart() 
{
    //---structural
    Run(new Proxy::Client);
}
//+------------------------------------------------------------------+
//| output                                                           |
//+------------------------------------------------------------------+
// Proxy::Client::Output
// real subject
相关推荐
时光追逐者2 分钟前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb
一弓虽7 分钟前
SpringBoot 学习
java·spring boot·后端·学习
晓数1 小时前
【硬核干货】JetBrains AI Assistant 干货笔记
人工智能·笔记·jetbrains·ai assistant
我的golang之路果然有问题1 小时前
速成GO访问sql,个人笔记
经验分享·笔记·后端·sql·golang·go·database
genggeng不会代码2 小时前
用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)
学习
lwewan2 小时前
26考研——存储系统(3)
c语言·笔记·考研
搞机小能手2 小时前
六个能够白嫖学习资料的网站
笔记·学习·分类
nongcunqq3 小时前
爬虫练习 js 逆向
笔记·爬虫
汐汐咯3 小时前
终端运行java出现???
笔记
The_cute_cat4 小时前
25.4.22学习总结
学习