裝飾指令

2004 年 1 月 24 日

這是一個非常常見的模式,而且非常簡單,它實際上只是應用於指令的裝飾模式。我見過它與 CommandOrientedInterface 一起使用。您也會聽到這稱為攔截器和面向切面編程的一種形式。

您從某些指令開始,通常是某種基本功能的形式,可能需要稍後新增一些額外功能。因此這可能是面向領域的指令,例如 PayInvoice。這些指令將具有一些執行方法。

// 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 的一大好處。

如今,許多事情都在面向切面的標語下執行此類事情。在某個時候,我將深入探討這一點,看看是否還有比這個模式更多可發揮之處。

這是有切面性的,但面向切面編程還有更多內容。在切面術語中,裝飾器為領域指令的 Execute 方法提供建議。但是為了做到這一點,您必須圍繞指令組織所有內容,因為只有 Execute 方法可以得到建議。更靈活的 AOP 工具(例如 aspectJ)允許您建議任何方法,甚至其他一些事情,例如欄位存取。