0

我正在寻找将对象分派到正确的“目标”对象的最佳方法。

我有一个基本命令类:Cmd,两个子类:BufferCmd 和 StateCmd。命令“GotoLine”派生自 BufferCmd,“ChangeCmd”派生自 StateCmd。BufferCmds 旨在转到 Buffer 类,而 StateCmds 旨在转到 State 对象。

我目前设置了访客模式,以便可以执行以下操作:

Buffer buffer;
State state;

Cmd *c;
GotoLineCmd gotoCmd = new GotoLineCmd (15);
ChangeCmd changeCmd = new ChangeCommand (...)

c = &gotoCmd;
c->accept (buffer);
c = &changeCmd;
c->accept (state);

我想使用访问者模式,因为我希望能够做一些大致如下的事情:

Cmd *cmds [5];
cmds [0] = new GotoLineCmd (...); 
cmds [1] = new CopyLineCmd (...); 
cmds [2] = new PasteCmd (...); 

foreach (Cmd *c in cmds) {
    c->accept (buffer);
}

不幸的是,为了使用它,我需要知道将命令发送到哪个对象。我希望能够做这样的事情:

Derive Buffer from Commandable
Derive State from Commandable

Commandables *commandables [1] = {new Buffer (), new State () };

// Then have the foreach type statement look like:
foreach (Cmd *c in cmds) {
    c->accept (commandables);
}

是否有最适合这种情况的模式?我什至应该使用访客模式吗?显然我想避免这种情况:

foreach (Cmd *c in cmds) {
    foreach (Commandable *cmdAbles in commandables) {
        if (c->accept (commandables)) {
              // Okay command accepted... 
              break;
        }
    }
}

谢谢

4

1 回答 1

3

听起来更像是您想要恰当命名的Command 模式

关键是将 的不同参数移动accept()到每个派生自 的类的构造函数中Cmd。例如,GotoLineCommand的构造函数会将行和缓冲区对象作为其构造函数的参数,并且它将存储指向缓冲区对象的指针或引用。

完成此操作后,您不再需要参数,accept()并且接口在派生自的所有类中都是相同的Cmd

class Buffer
{
   public:
      void gotoLine(int line);
};

class Cmd
{
   public:
      virtual void accept() = 0;
};

class GotoLineCommand: public Cmd
{
   public:
      GotoLineCommand(Buffer & buffer, int line) :
         buffer_(buffer),
         line_(line)
      {
      }

      virtual void accept()
      {
         buffer_.gotoLine(line_);
      }

   private:
      Buffer & buffer_;
      int line_;
};
于 2009-12-15T20:30:51.620 回答