代理模式

代理模式

目的与概念

代理模式是一种结构型模式,其目的是为调用者提供中间层以控制对某个对象的访问,即在调用者与被调用者之间添加一层代理层,调用代理接口层来实现被调用者复杂的操作;

代理模式提供了中间层,屏蔽了实现层复杂且用户并不想知道的操作,让调用者只需关注自己所需求的操作,这样调用者就可以方便地使用这些接口,而不用了解底层的具体操作;

其另一个优点是,此中间层起到了隔离调用者与实现者的作用,当需求变更时,可以仅修改代理类而不修改具体实现,提高了代码的复用性与扩展性;

代理模式与一些其他结构型模式虽目的不同,但在思想及做法上有很多相似的地方,即往往要添加一层中间层以实现自己的目标;

代理模式思想的使用非常普遍,工程实践中,我们常会有意无意地应用代理模式的思想,只是很多时候我们并没有意识到而已;

代码示例

下述代码简陋地展示了代理模式的某一种代码实现方式,代码仅作演示:

//  ----------------------------------------------------------------------------
/**
 * @file  Subject.h
 */
// 接口类,可以被用户看到
class Subject {
public:
    virtual ~Subject() {}
    virtual void operate() = 0;
};


//  ----------------------------------------------------------------------------
/**
 * @file  SubjectProxy.h
 */
// 代理类,可以被用户看到
#include "Subject.h"
class RealSubject;
class SubjectProxy : public Subject {
public:
    void operate() override;
private:
    void preProcess();
    void postProcess();
    std::unique_ptr<RealSubject> m_realSubject;
}
//  ----------------------------------------------------------------------------
/**
 * @file  SubjectProxy.cpp
 */
#include "SubjectProxy.h"
#include "RealSubject.h"
SubjectProxy::SubjectProxy()
{
    m_realSubject = std::make_unique<RealSubject>();
}
void SubjectProxy::operate() 
{
    preProcess();
    m_realSubject->operate(); // 调用真正的实现函数
    postProcess();
}
void SubjectProxy::preProcess()
{
    // 前处理操作
    // ...
}
void SubjectProxy::postProcess() 
{
    // 后处理操作
    // ...
}


//  ----------------------------------------------------------------------------
/**
 * @file  RealSubject.h
 */
// 真正的实现类,不被用户看到
#include "Subject.h"
class RealSubject : public Subject {
public:
    void operate() override {
        // 具体实现方法代码,一般会放在 RealSubject.cpp 中
        // ...
    }
    // 其他各种复杂的操作代码
    // ...
};


//  ----------------------------------------------------------------------------
/**
 * @file  main.cpp
 */
// 调用代码
#include "SubjectProxy.h"
int main()
{
    std::unique<Subject> subj = std::make_unique<SubjectProxy>();
    subj->operate();
    
    // ...
    
    return 0;
}

代理模式不一定要使用如上述代码的纯虚接口类与继承这样的方式来实现,上述代码仅仅是其中一种方式的演示;

实际工程中,代理模式实现是十分复杂的,而且会含有很多变化,并没有固定的套路。例如:STL 中的智能指针、Qt 库中 QString 的写时复制技术等,都包含了代理模式的影子,关于这些技术的详细阐述,并非本文重点,故不赘述,若要了解,可自行查阅资料;

参考


本文作者: 王同学