下面带来一个常用的设计模式——代理模式(好久没更新这个系列了……………………)
1. 情景与意图
还记的模板方法模式,有一种说法叫晚绑定。晚绑定其实就是无法预知与后面未知的进行通信,也就是说无法直接访问或者达到某个目的。如果了解UIKit,其中常用的一个UITableView,它主要作用与通讯录列表,好友列表等UI,我们在创建一个这样的UI的时候,它是不知道我们一共有多少联系人,QQ好友等。因此它有一个dataSourceDelegate,就是数据代理,用它来获取数据。
现实中比如你想买国外的一个化妆品,但是自己无法去,所以找了代购,这个代购就是代理。理解代理模式就从字面意思开始。
2. 代理模式
在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
下面就用第一节的代购来实现代理
3. 代购
先定义一个化妆品
struct Cosmetic {
std::string _name;
std::string _commodityCode;
};
首先定义代理的接口,是这个代理人的要做的事情。
class DPCustomer; // 想找人代购的消费者
class DPAbstactExclusive {
public:
virtual Cosmetic getExclusive(DPCustomer* customer, const std::string& exclusiveName) = 0;
};
下面这个就是一个具体的代购的人。
class DPPurchasingAgent : public DPAbstactExclusive {
public:
virtual Cosmetic getExclusive(DPCustomer* customer, const std::string& exclusiveName);
};
Cosmetic DPPurchasingAgent::getExclusive(DPCustomer* customer, const std::string& exclusiveName) {
// …………
// 复杂的此操作
// 飘洋过海………………等等
// …………
Cosmetic cosmetic;
cosmetic._name = exclusiveName;
cosmetic._commodityCode = exclusiveName + "code";
std::cout << "Purchasing " << exclusiveName << " to " << customer->getName() << "\n";
return cosmetic;
}
class DPCustomer {
std::string _name;
DPAbstactExclusive* _delegate;
public:
DPCustomer(std::string name, DPAbstactExclusive* delegate);
std::string getName();
void boughtExclusive(const std::string& exclusiveName);
};
// 主要的方法
void DPCustomer::boughtExclusive(const std::string& exclusiveName) {
Cosmetic cosmetic = _delegate->getExclusive(this, exclusiveName);
std::cout << "[" << _name << "] bought a cosmetic\n";
std::cout << "[" << cosmetic._name << " : " << cosmetic._commodityCode << "]\n";
}
现在我们来看看怎么代理的。
int main() {
DPAbstactExclusive* delegate = new DPPurchasingAgent(); // 首先生成一个代购
DPCustomer cus("李四", delegate); // 然后是一个消费者,这个消费者可以是很多人, DPCustomer cus("张三", delegate);
cus.boughtExclusive("大宝");
return 0;
}
4. 总结
增加一层中间层,是在复杂系统中解决的问题的常见手段。代理模式也是常见的一种设计模式。
代理设计模式源码:【代理设计模式C++源码】