简体   繁体   English

哪种设计模式/ RTTI

[英]Which Design Pattern / RTTI

I'm looking for the best way to dispatch objects to the correct "target" object. 我正在寻找将对象分派到正确的“目标”对象的最佳方法。

I have a base command class: Cmd, two sub-classes: BufferCmd and StateCmd. 我有一个基本的命令类:Cmd,两个子类:BufferCmd和StateCmd。 Command "GotoLine" is derived from BufferCmd and "ChangeCmd" is derived from StateCmd. 命令“ GotoLine”从BufferCmd派生,“ ChangeCmd”从StateCmd派生。 BufferCmds are intended to go to a Buffer class and StateCmds are intended to go to a State object. BufferCmds用于转到Buffer类,StateCmds用于转到State对象。

I currently have a Visitor pattern set up so that I can do something like: 我目前已设置了一个访问者模式,以便可以执行以下操作:

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);

I want to use the Visitor pattern because I'd like to be able to do something roughly like: 我想使用Visitor模式,因为我希望能够做一些大致的事情:

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

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

Unfortunately in order to use this I need do know what object to send the command to. 不幸的是,为了使用它,我需要知道将命令发送到哪个对象。 I'd like to be able to do something like this: 我希望能够执行以下操作:

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);
}

Is there a pattern that is most appropriate for this type of situation? 是否有最适合这种情况的模式? Should I even be using the Visitor pattern? 我是否应该使用“访客”模式? Obvious I want to avoid this: 显然我想避免这种情况:

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

Thanks 谢谢

Sounds more like you want the aptly-named Command pattern . 听起来更像是您想要适当命名的Command模式

The key is to move the differing parameters of accept() into the constructor of each class derived from Cmd . 关键是将accept()的不同参数移到从Cmd派生的每个类的构造函数中。 For example, GotoLineCommand 's constructor would take the line and the buffer objects as parameters to its constructor, and it would store a pointer or reference to the buffer object. 例如, GotoLineCommand的构造函数会将行和缓冲区对象作为其构造函数的参数,并将存储指向缓冲区对象的指针或引用。

Once you've done that, you no longer need the parameters to accept() and the interface is the same across all classes derived from Cmd 完成此操作后,就不再需要参数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_;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM