条款19 command 模式与好莱坞法则

当一个函数对象被当做回调时候,就是一个command模式的实例

什么是回调? 回调就是框架知道什么时候干一些事情,但是具体干什么,或许框架一无所知(因为回调函数不是他设计的),而用户则知道发生一个特定事件的时候,应该干什么,但是他不知道什么时候去干这个事情。这两个部分共同构成了一个完整的应用程序。

常见的回调函数的实现方式是函数指针,类似如下的方式:

extern void playmusic();

//。。。

button * new Button(“anko no nama”);

b->setAction( playmusic);

registerButtonWithFramework(b);

但是现实中我们可能有这样的需求,设计播放的歌曲,他所使用的编码,和解码器等等, 一个比较好的方式是利用函数对象代替函数指针。

使用这个方式有一个显而易见的好处,函数对象可以封装数据,同时函数对象可以虚拟成员表现出动态行为。

   1:  class Action
   2:  {
   3:  public
   4:      virtual ~Action();
   5:      virtual void operation()()=0;
   6:      virtual Action *clone() const = 0; //原型(prototype);
   7:  }
   8:   
   9:  class Button
  10:   
  11:  {
  12:   
  13:  public
  14:      Button(const std::string &label ): label_( label),action_(0){}
  15:      void setAction(const Action *newAction)
  16:      {
  17:          Action *temp = newAction.clone();
  18:          delete action_;
  19:          action_ = temp;
  20:      }
  21:   
  22:      void onClick() const
  23:      {
  24:          if( action_ ) (*action)();
  25:      }
  26:  private:
  27:      std::string label_;
  28:      Action *action;
  29:  }
  30:   
  31:  class PlayMusic : public Action
  32:  {
  33:  public:
  34:      PlayMusic( const string &songFile ):song_(songFile){}
  35:      void operator ()();
  36:      Action *clone();
  37:  private:
  38:      MP3 song_;
  39:  }
  40:   

被封装的数据既保持了playmusic的函数对象的灵活性,有保持了他的安全性;

   1:  Button *b = new Button( “anoko no nama” );
   2:  auto_ptr<PlayMusic> song( ne PlayMusic(“anokononama.mp3”));
   3:  b->setAction( song.get)

可以看做是函数对象的又一个比较好的应用;

原文地址:https://www.cnblogs.com/hwtxf/p/3518126.html