rails Forwardable def_delegators
设计模式中常说,组合优于继承,可是组合带来的问题是,你可能要在类中添加wrap方法,委托别的类去做这个实现,举例如下:
1 class Robot
2 def initialize
3 @heat_sensor = HeatSensor.new
4 @arm = RobotArm.new
5 end
6
7 def measure_heat(scale="c")
8 @heat_sensor.measure(scale)
9 end
10
11 def stack(boxes_number=1)
12 @arm.stack(boxes_number)
13 end
14
15 def package
16 @arm.package
17 end
18 end
19
20 class HeatSensor
21 # Celsius or Fahrenheit scale
22 def measure(scale="c")
23 t = rand(100)
24 t = scale=="c" ? t : t * (9/5)
25 puts "Heat is #{t}° #{scale.upcase}"
26 end
27 end
28
29 class RobotArm
30 def stack(boxes_number=1)
31 puts "Stacking #{boxes_number} box(es)"
32 end
33
34 def package
35 puts "Packaging"
36 end
37 end
Robot这个类就包装了stack, package 以及measure_heat三个方法,都是委托其他类实现,这样的写法很土,借助于ruby强大的语言特性,其实你完全可以不用写如此丑陋的代码,你只要写成如下方式就好了
1 class Robot
2 # Extending provides class methods
3 extend Forwardable
4 # Use of def_delegators
5 def_delegators :@arm,:package,:stack
6 # Use of def_delegator
7 def_delegator :@heat_sensor, :measure ,:measure_heat
8 def initialize
9 @heat_sensor = HeatSensor.new
10 @arm = RobotArm.new
11 end
12 end
def_delegator(obj, method, alias = method)
def_delegators(obj, *methods)