第10章 オブジェクトに代理を立てる: Proxy part1
Ruby
Published: 2019-06-26

「Rubyによるデザインパターン」の読書メモです。

Proxy パターンは下記の問題の解決策となります。

  • オブジェクトへのアクセス制御
  • 場所に依存しないオブジェクトの取得方法の提供
  • オブジェクト生成の遅延

プロキシーが気にするのは、何かをすることが許されているのは誰で、許されていないのが誰なのかということです。

Proxy パターンの例

3つの問題について、解決させるように試みたコードです。

test.rb

class BankAccount
  attr_reader :balance

  def initialize(starting_balance=0)
    @balance = starting_balance
  end

  def deposit(amount)
    @balance += amount
  end

  def withdraw(amount)
    @balance -= amount
  end
end

require 'etc'
class BankAccountProxy
  def initialize(starting_balance, owner_name, &creation_block)
    @starting_balance = starting_balance
    @owner_name = owner_name
    @creation_block = creation_block
  end

  def balance
    check_access
    subject.balance
  end

  def deposit(amount)
    check_access
    subject.deposit(amount)
  end

  def withdraw(amount)
    check_access
    subject.withdraw(amount)
  end

  def check_access
    if Etc.getlogin != @owner_name
      raise "Illegal access: #{Etc.getlogin} cannot access account."
    end
  end

  def subject
    @subject || (@subject = @creation_block.call)
  end
end

account = BankAccount.new(100)
account.deposit(50)
account.withdraw(10)
p account.balance

account2 = BankAccountProxy.new(account.balance, 'hogehoge') { BankAccount.new(300) }
account2.deposit(50)
account2.withdraw(10)
p account2.balance

出力結果

$ ruby test.rb
140
340