programming-examples/ruby/Patterns/proxy.rb
2019-11-15 12:59:38 +01:00

124 lines
3.1 KiB
Ruby

# When building a proxy, we could implement a method for each method in the
# underlying object. However, this leads to a lot of repeated code and tightly
# couples the proxy with the underlying object. A better alternative is to pass
# method calls direcly to the underlying object. Ruby includes a method that is
# perfect for this situation called method_missing.
# Object witch is decorated
class BankAccount
attr_reader :balance
def initialize(balance = 0)
@balance = balance
end
def deposit(amount)
balance += amount
end
def withdraw(amount)
balance -= amount
end
end
# Proxy
# Do not use attr_reader for accessing to proxy object
class BankAccountProxy
def initialize(real_object)
@real_object = real_object
end
def balance
@real_object.balance
end
def deposit(amount)
@real_object.deposit(amount)
end
def withdraw(amount)
@real_object.withdraw(amount)
end
end
# Protection proxy
# Are you working on an MNC? If so, we might be well aware of the proxy server
# that provides us internet by restricting access to some sort of websites like
# public e-mail, social networking, data storage etc. The management feels that,
# it is better to block some content and provide only work related web pages.
# Proxy server does that job. This is a type of proxy design pattern
class BankAccountProtectionProxy
def initialize(real_account, owner_name)
@subject = real_account
@owner_name = owner_name
end
def deposit(amount)
check_access
@subject.deposit(amount)
end
def withdraw(amount)
check_access
@subject.withdraw(amount)
end
def balance
check_access
@subject.balance
end
def check_access
# Implementation
end
end
# Virtual proxy
# In place of a complex or heavy object, use a skeleton representation. When an
# underlying image is huge in size, just represent it using a virtual proxy
# object and on demand load the real object. You know that the real object is
# expensive in terms of instantiation and so without the real need we are not
# going to use the real object. Until the need arises we will use the virtual proxy.
class BankAccountVirtualProxy
def initialize(&creation_block)
@creation_block = creation_block
end
def deposit(amount)
subject.deposit(amount)
end
def withdraw(amount)
subject.withdraw(amount)
end
def balance
subject.balance
end
def subject
@subject ||= @creation_block.call
end
end
# Remote proxy
# In distributed object communication, a local object represents a remote object
# (one that belongs to a different address space). The local object is a proxy
# for the remote object, and method invocation on the local object results in
# remote method invocation on the remote object. Think of an ATM implementation,
# it will hold proxy objects for bank information that exists in the remote server.
# Server part
class BankAccountRemoteProxy
# implementation
end
URI = 'druby://path_to_domain:port'
DRb.start_service(URI, BankAccountRemoteProxy.new)
DRb.thread.join
# Client part
URI = 'druby://path_to_domain:port'
proxy = DRbObject.new_with_uri(URI)
proxy.balance