Created
February 11, 2015 20:43
-
-
Save RedFred7/c1d7de9da194922305b2 to your computer and use it in GitHub Desktop.
Design Patterns the Ruby way: proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####### PROXY PATTERN ############# | |
### way #1 | |
## The following code implements the proxy pattern in the traditional | |
## manner, i.e. the proxy mirrors the methods of the real object (e.g | |
## drive) and delegates accordingly | |
class RealCar | |
def drive | |
puts "vroom,vroom..." | |
end | |
end | |
class ProxyCar | |
def initialize(real_car, driver_age) | |
@driver_age = driver_age | |
@real_car = real_car | |
end | |
def drive | |
car = get_real_car | |
check_access ? car.drive : puts("Sorry, you're too young to drive") | |
end | |
def check_access | |
@driver_age > 16 | |
end | |
def get_real_car | |
@real_car || (@real_car = Car.new(@driver_age)) | |
end | |
end | |
## this is the client for our proxy. When it calls the drive method | |
## we're going to give it our proxy to drive instead of the real car | |
class Client | |
attr_reader :age | |
def initialize(age) | |
@age = age | |
end | |
def drive(car) | |
car.drive | |
end | |
end | |
tom = Client.new(15) | |
car = RealCar.new() | |
proxy = ProxyCar.new(car, tom.age) | |
tom.drive(proxy) | |
### way #2 | |
## The following code uses dynamic dispatching in our Proxy, so we | |
## capture any method call to our Proxy via #method_missing and | |
## re-direct it to the real object | |
#remove previous definition of ProxyCar | |
Object.send(:remove_const, :ProxyCar) | |
class ProxyCar | |
def initialize(real_car, driver_age) | |
@driver_age = driver_age | |
@real_car = real_car | |
end | |
def method_missing(name, *args) | |
car = get_real_car | |
check_access ? car.send(name, *args) : puts("Sorry, can't do this") | |
end | |
def check_access | |
@driver_age > 16 | |
end | |
def get_real_car | |
@real_car || (@real_car = Car.new(@driver_age)) | |
end | |
end | |
## we create and use our client and proxy in the same way as before, | |
## even though we're using dynamic dispatching in our proxy | |
jerry = Client.new(25) | |
car = RealCar.new() | |
proxy = ProxyCar.new(car, jerry.age) | |
jerry.drive(proxy) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment