修飾されたコマンド

2004年1月24日

これは非常に一般的なパターンであり、非常に簡単です。これは単に、コマンドに適用されるデコレータパターンです。私は、CommandOrientedInterfaceで多く使用されているのを見てきました。これには、インターセプターや、アスペクト指向プログラミングの一形態としても言及されています。

基本的な機能のためにいくつかのコマンドを開始します。後からさらに機能を追加する必要がある場合があります。これは、PayInvoiceなどのドメイン指向コマンドである可能性があります。これらのコマンドには、何らかの形式のexecuteメソッドがあります。

// psuedo C#
class PayInvoiceCommand : Command ...
void Execute() {
  // do interesting domain logic
}

トランザクション内でこれを実行したいとします。コマンドは、適切なトランザクションデコレータで修飾できます。

// pseudo C#
class TransactionalDecorator : CommandDecorator ...
  void Execute() {
    Transaction t = TransactionManager.beginTransaction();
    try {
      Component.Execute();
      t.commit();
    } catch (Exception) {
      t.rollback();
    }
  }
    

この方法で、セキュリティチェックを行うこともできます。

// pseduo C#
class SecurityDecorator : CommandDecorator ...
  void Execute() {
    if (passesSecurityCheck())
      Component.Execute();
  }

これらのクラスが配置されれば、それらを簡単に組み合わせて、適切な種類の振る舞いを取得できます。

//psuedo C#
  // Transaction Invoice Payment
  Command c = new TransactionalDecorator(new PayInvoiceCommand(invoice));
  c.Execute();
  //Transactional and secure payment
  Command c = new SecurityDecorator(
                  new TransactionalDecorator(
                      new PayInvoiceCommand(invoice)));
  c.Execute();

確かに、動的に振る舞いを追加できるこの機能は、CommandOrientedInterfaceの大きな利点の1つです。

多くのことは、近年アスペクト指向のバナーの下でこのようなことを行っています。いずれにしてもここで、このパターン以上のものがプレイされているかどうかを確認するために、さらに掘り下げる予定です。

これは側面的ですが、アスペクト指向プログラミングにはこれ以上のものがあります。アスペクト用語では、デコレータはドメインコマンドのExecuteメソッドにアドバイスを提供します。ただし、これを行うには、Executeメソッドのみがアドバイスを受けることができるため、コマンドの周りにすべてを整理する必要があります。aspectJなどのより柔軟なAOPツールでは、任意のメソッドやフィールドアクセスなどの他のものにもアドバイスできます。