Skip to content

Instantly share code, notes, and snippets.

@RedFred7
Created February 11, 2015 20:43
Show Gist options
  • Save RedFred7/c1d7de9da194922305b2 to your computer and use it in GitHub Desktop.
Save RedFred7/c1d7de9da194922305b2 to your computer and use it in GitHub Desktop.
Design Patterns the Ruby way: proxy
####### 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