您的位置:首页 > 编程语言 > Ruby

ruby 元编程 学习记录-关于动态代理

2014-05-11 19:37 423 查看
ruby元编程的动态代理的说明中有一个例子,是说明如何用delegate类如何快速创建一个动态代理的。

动态代理的功能是将对象不认识的方法转发给封装它的Assistant类做处理

先看看原来的例子

require 'delegate'
class Assistant
def initialize(name)
@name = name
end

def read_email
puts "(#{@name}) It's mostly spam!"
end

def check_schedule
puts "(#{@name})You have a meeting today!"
end
end

class Manager < DelegateClass(Assistant)

def initialze(assistant)
super(assistant)
end
def attend_meeting
puts "please hold my calls"
end

end
frank = Assistant.new("Frank")
frank.check_schedule
frank.read_email

anne = Manager.new(frank)
anne.attend_meeting 
anne.read_email
anne.check_schedule
#结果输出
(Frank)You have a meeting today!
(Frank) It's mostly spam!
please hold my calls
(Frank) It's mostly spam!
(Frank)You have a meeting today!


看这个例子的过程中产生了一个疑问,这个例子中的动态代理和继承有什么区别?
这里直接如果类Manger直接继承Assistant的话,也能在这种情况下,直接调用到父类的read_email,check_schedule方法。为什么一定要通过

delegate来创建呢?

修改了下源码,让Manger继承Assistant。比较下输出

(Frank)You have a meeting today!

(Frank) It's mostly spam!

please hold my calls

(#<Assistant:0x31788bc>) It's mostly spam!

(#<Assistant:0x31788bc>)You have a meeting today!

可以发现,这里name参数的位置,在Manger对象的情况下,输出的是类实例,对象。所以,个人理解这里使用代理场景的意义在于,“代理”这个词

这里是将当前Manger对象需要处理的内容完全交给了Assistant类的对象处理,包括使用的成员参数等,实际上做出处理的是Assistant类对象。

如果是继承,则处理主体还是Manger。

修改定义对象的方式

anne = Manager.new("Frank")
anne.attend_meeting
anne.read_email
anne.check_schedule
rubytest.rb:37: undefined method `read_email' for "Frank":String (NoMethodError)
please hold my calls

发现找不到对应的方法,这种情况在继承方式中是不会出现的。

但是在动态代理中显然不行,需要在定义Manger类对象时,给出Assistant对象作为入参,这样才能在Method_miss的时候找到对应的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ruby delegate