参考:
代理模式(代理设计模式)详解 (biancheng.net)
design-patterns-cpp/Proxy.cpp at master · JakubVojvoda/design-patterns-cpp · GitHub
一、什么是代理模式?
定义:由于某些原因,用户不适合直接引用目标对象,需要一个代理以控制对该对象的访问。创建一个代理对象,作为访问对象和目标对象之间的中介,这就是代理模式。
比如,购买火车票不一定要去火车站买,可以通过 12306 网站或者去火车票代售点买;租房可以通过中介平台;代理将自己伪装成数据库对象,可在客户端或实际数据库对象不知情的情况下处理延迟初始化和缓存查询结果的工作。
二、实现
代理(Proxy )模式包含以下主要角色:
- 抽象主题(Subject)类:用户需要访问的接口。
- 真实主题(Real Subject)类:实现真正的业务功能。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
代理模式有两种实现方式:静态代理、动态代理。
静态代理:新增一个业务功能,需要增加代理就要新增代理类。
动态代理:在程序运行时,运用反射机制动态创建代理类。但C++ 缺乏反射机制,可使用类模板方法代替。
1、静态代理
/*
* C++ Design Patterns: Proxy
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
* 2016
*
* Source code is licensed under MIT License
* (for more details see LICENSE)
*
*/
#include <iostream>
/*
* 抽象主题类
* 定义用户需要访问的接口
*/
class Subject
{
public:
virtual ~Subject() { /* ... */ }
virtual void request() = 0;
// ...
};
/*
* 真实主题类
* 实现真正的业务功能
*/
class RealSubject : public Subject
{
public:
void request()
{
std::cout << "Real Subject request" << std::endl;
}
// ...
};
/*
* 代理(Proxy)类
* 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
*/
class Proxy : public Subject
{
public:
Proxy()
{
subject = new RealSubject();
}
~Proxy()
{
delete subject;
}
void request()
{
subject->request();
}
// ...
private:
RealSubject *subject;
};
int main()
{
Proxy *proxy = new Proxy();
proxy->request();
delete proxy;
return 0;
}
2、动态代理
class Person{
std::string mName;
Person(std::string pName): mName(name){}
void printName(){
std::cout << mName << std::endl;
}
};
template <class T >
class Wrap {
T * p ;
public:
Wrap (T * pp ) :p (pp) { }
Call_proxy <T> operator ->() {
prefix ();
return Call_proxy<T>(p);
}
};
template <class T >
class Call_proxy {
T * p ;
public :
Call_proxy (T * pp ) :p (pp ){ }
˜Call_proxy () {
suffix ();
}
T * operator ->() {
return p ;
}
};
三、优缺点
优点
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
缺点
- 代理模式会造成系统设计中类的数量增加;
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;