Résumé des patrons de conception expliqués dans le livre Design Patterns in Ruby
View the Project on GitHub armandfardeau/design-patterns-in-ruby
We want to have more control over how and when we access to a certain object.
With the proxy pattern we create an object, proxy, that has a reference to the real object we want to access. Then, whenever the client calls it, it simply forwards the request to the real one. There are three main scenarios where this pattern might be useful:
Let’s consider a BankAccount
object:
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
If we wanted to control who accesses it, we could build a proxy object that introduces some checks before delegating calls to the bank account:
require 'etc'
class AccountProtectionProxy
def initialize(real_account, owner_name)
@subject = real_account
@owner_name = owner_name
end
def deposit(amount)
check_access
return @subject.deposit(amount)
end
def withdraw(amount)
check_access
return @subject.withdraw(amount)
end
def balance
check_access
return @subject.balance
end
def check_access
if Etc.getlogin != @owner_name
raise "Illegal access: #{Etc.getlogin} cannot access account."
end
end
end
Maybe what we want to do is creating the bank account object only when it’s really needed. We could create a proxy that initializes the real object only when one of its methods is called, and keep a cached copy for further calls:
class VirtualAccountProxy
def initialize(starting_balance=0)
@starting_balance=starting_balance
end
def deposit(amount)
s = subject
return s.deposit(amount)
end
def withdraw(amount)
s = subject
return s.withdraw(amount)
end
def balance
s = subject
return s.balance
end
def subject
@subject || (@subject = BankAccount.new(@starting_balance))
end
end