0

オブジェクトを正しい「ターゲット」オブジェクトにディスパッチする最良の方法を探しています。

基本コマンド クラス: Cmd、2 つのサブクラス: 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 patternが必要なように思えます。

重要なのは、 の異なるパラメータを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 に答える