博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

delegate委托模式

Posted on 2014-09-19 17:52  bw_0927  阅读(243)  评论(0)    收藏  举报

http://www.firedragonpzy.com.cn/index.php/archives/2640

http://www.uml.org.cn/j2ee/200411036.htm

 

delegator---->delegate

caller-------->callee

 

前一篇文章讨论了cocos2d-x里面的中介者模式,但是,由于概念把握上面的偏差,我把GoF的中介者模式搞混淆了。幸好有读者给我提出了这个问题,我在上一篇文章中也补充说明了。虽然我谈到的应用场景跟中介者模式有点类似,但是,经典的模式就是模式,我不能随便篡改,更不能张冠李戴。所以,这篇文章我将谈到的是委托模式(delegation pattern),而不是GoF里面的代理模式(Proxy pattern),虽然delegate也可以翻译成“代理”,但是,为了以示区别,这里使用委托。当然,文章观点如果有误,欢迎大家指出。

在讨论cocos2d-x里面的委托模式之前,先来讲讲什么是委托,以及c++里面如何实现委托。所谓委托,我的理解是,一个对象需要实现某个功能,它不用自己去实现,而是委托其它对象给它实现。对于客户端程序来讲,你可以定制被委托对象,从来实现所需要的功能。这句话有点拗口,而且不容易理解。

让我们先来看一段代码:

class RealPrinter { // the "delegate"
 public:
 void print() {
 //do something
 }
 };
 
class Printer { // the "delegator"
 public:
 Printer(): p(new RealPrinter()){} // create the delegate
 void print() {
 p->print(); // delegation
 }
 ~Printer(){
 if(NULL != p){
 delete p;
 p = NULL;
 }
 }
 private:
 RealPrinter *p;
 };
 
int main()
 {
 Printer *p = new Printer;
 p->print(); //client don’t know the exists of delegate class
 delete p;
 }

  

Printer这个类要实现打印功能,它不是自己去实现,而是委托RealPrinter这个类来实现。更一般化的示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class PrinterDelegate{
 public:
 virtual ~PrinterDelegate(){} // why virtual function , see Effective c++ Item 7.
 virtual void print() = 0;
 };
 
class RealPrinter : public PrinterDelegate { // the "delegate"
 public:
 void print() {
 //do something
 }
 };
 
class Printer{
 public:
 Printer():delegate(new RealPrinter){}
 void print(){
 if (NULL != delegate) {
 delegate->print();
 }
 }
 ~Printer(){
 if(NULL != delegate){
 delete delegate;
 delegate = NULL;
 }
 }
 private:
 PrinterDelegate *delegate;
 };
 
int main()
 {
 Printer *p = new Printer;
 p->print(); //client don’t know the exists of delegate class
 delete p;
 }

看完这个实现之后,相信大家对objc里面的delegate如何用c++实现也差不多有了解了吧。其实很简单,就是一个针对接口编程嘛。关于如何实现mvc,Cocos2d-x中文论坛里面已经有一个人给出了一个样例实现,具体我没怎么看,大家参考一下吧。