0

フレームワークを設計していて、非同期または同期で実行されるサブオブジェクトを持つ複合オブジェクトがあります。同期実行のものの場合、通常、特定のサブアイテムが終了した後に複合オブジェクトで実行する必要がある特定のタイプのロジックがあります。

問題は、サブアイテムが多数あり、サブアイテムごとに、サブアイテムごとに異なる処理が行われる可能性があることです。単純化を目指していたため、同期アイテムをキューに入れて、複合アイテムがそれらをポップするだけでした。 1つずつ実行します。サブアイテム#2が終了したら、返されたデータを取得してxyz()を実行するように、サブアイテムを追跡する最もクリーンな方法は何でしょうか。

4

3 に答える 3

1

コマンドパターン。これは、コマンドのリストを維持する CompositeCommand のように聞こえます。各 Command には execute() 操作があり、CompositeCommand の execute 操作はコマンドのリストを反復処理し、各 Command の execute を呼び出します。CompositeCommand の execute() メソッドで各反復の後に xyz() を実行するロジックを持つことができます。

また、各コマンドは異なる方法で処理できると述べましたが、これは戦略によって実装できます。

于 2012-07-11T16:04:05.220 に答える
1

後処理オプションが限られている場合は、訪問者パターンのようなものを検討してください。

コンポジットは、必要な後処理のタイプごとに 1 つのメソッドを実装し、サブアイテムは、コンポジットのインスタンスを取得し、サブアイテムの種類に応じて後処理メソッドの 1 つを呼び出すメソッドを実装します。は。すでにexecuteサブ項目を ing しているので、代わりにそのメソッドの最後で後処理メソッドを呼び出させることができます。

インターフェイス定義をスキップする例:

class CompositeA implements Composite {
  public ? process() {
    for (Sub subItem : subItems) {
      subItem.execute();
      subItem.postProcess(this);
    }
  }

  public ? postProcessA(SubA subItem) {
    //do something with SubA
  }

  public ? postProcessB(SubB subItem) {
    //do something with SubB
  }
}

class CompositeB implements Composite {
  public ? process() {
    for (Sub subItem : subItems) {
      subItem.execute();
      subItem.postProcess(this);
    }
  }

  public ? postProcessA(SubA subItem) {
    //do something else with SubA
  }

  public ? postProcessB(SubB subItem) {
    //do something else with SubB
  }
}

class SubA implements Sub {
  public ? execute() {
    //doSomething
  }

  public ? postProcess(Composite composite) {
    comp.postProcessA(this);
  }
}

class SubB implements Sub {
  public ? execute() {
    //doSomething
  }

  public ? postProcess(Composite composite) {
    comp.postProcessB(this);
  }
}
于 2012-07-11T16:25:20.193 に答える
0

依存するロジックを独自の操作に移動することをお勧めします。

abstract Operation
{
   abstract ? Execute(? arg);  // override in subclass to do work
}

abstract PostProcessOperation : Operation
{

   Operation _sourceOp;

   Operation(Operation sourceOp)
   {
      _sourceOp = sourceOp;
   }

   override ? Execute(? arg)
   {      
      ? sourceResult = _sourceOp.Execute(arg);
      return PostProcess(sourceResult);
   }   

   abstract ? PostProcess(? arg); // override in subclass to do work with results of the source op Execute

}

次に、たとえば、処理後のコンソール ロギングを操作に追加するには、次のようにします。

class ResultLogOp : PostProcessOperation
{
   override ? PostProcess(? arg)
   {
      Console.Writeline(arg.ToString());
   }
}

例をさらに進めるために、ファイルの削除操作があり、その成功をログに記録して後処理したいとします。

DeleteFileOp deleteFile = DeleteFileOp(fileToDelete);

ResultLogOp loggedDeleteFile = new ResultLogOp(deleteFile);

operations.Enque(loggedDeleteFile); 

または、使用方法が異なる場合は、タイプに基づいて追加された特定のキー操作をコンテナー クラスでラップできる可能性があります。

void Add(Operation child)
{
   if (child is ImportantType)
   {
      _operations.Add(new ResultLogOp(child);  // add logging transparently on the fly
   }
}

このコンセプトのバリエーションは無限大です。

于 2012-07-12T17:10:41.353 に答える