顧客が本当に必要だったDCI

顧客が説明した要件


アーキテクトのDCI

http://rubysource.com/dci-the-evolution-of-the-object-oriented-paradigm/

class TransferringMoney
  include Context

  def self.transfer source_account_id, destination_account_id, amount
    source = Account.find(source_account_id)
    destination = Account.find(destination_account_id)
    TransferringMoney.new(source, destination).transfer amount
  end 

  attr_reader :source_account, :destination_account
  def initialize source_account, destination_account
    @source_account = source_account.extend SourceAccount
    @destination_account = destination_account.extend DestinationAccount
  end 

  def transfer amount
    in_context do
      source_account.transfer_out amount
    end 
  end 

  module SourceAccount
    include ContextAccssor

    def transfer_out amount
      raise "Insufficient funds" if balance < amount
      decrease_balance amount
      context.destination_account.transfer_in amount
      update_log "Transferred out", amount
    end
  end

  module DestinationAccount
    include ContextAccssor

    def transfer_in amount
      increase_balance amount
      update_log "Transferred in", amount
    end
  end
end


プログラマMVC

class TransferringMoney
  def self.transfer source_account_id, destination_account_id, amount
    source = Account.find(source_account_id)
    destination = Account.find(destination_account_id)
    TransferringMoney.new(source, destination).transfer amount
  end

  def initialize source_account, destination_account
    @source_account = source_account
    @destination_account = destination_account
  end

  def transfer amount
    transfer_out amount
  end

private

  def transfer_out amount
    raise "Insufficient funds" if balance < amount
    @source_account.decrease_balance amount
    transfer_in amount
    @source_account.update_log "Transferred out", amount
  end

  def transfer_in amount
    @destination_account.increase_balance amount
    @destination_account.update_log "Transferred in", amount
  end
end


顧客が本当に必要だった関数

def transfer(source_account_id, destination_account_id, amount)
  source = Account.find(source_account_id)
  destination = Account.find(destination_account_id)

  source.decrease_balance amount
  destination.increase_balance amount
  destination.update_log "Transferred in", amount
  source.update_log "Transferred out", amount
end

・・・

DCIのサンプルって「関数」でよくない?って思うようなの多いよね、と・・・。