数据库类
class DS
def initialize # connect to data source...
def get_mouse_info(id) #...
def get_mouse_price(id) #...
def get_keyboard_info(id) #...
def get_keyboard_price(id) #....
#....
ruby调用类
class Computer
def initialize(computer_id, data_source)
@id=computer_id
@data_source=data_source
end
def mouse
info=@data_source.get_mouse_info(@id)
price=@data_source.get_mouse_price(@id)
result="Mouse: #{info} $#{price}"
return "* #{result} " if price>100
end
def keyboard
info=@data_source.get_keyboard_info(@id)
price=@data_source.get_keyboard_price(@id)
result="Mouse: #{info} $#{price}"
return "* #{result} " if price>100
end
end
如何对上面的代码进行重构主要有两种方法:
1 动态方法和动态派发
class Computer
def initialize(computer_id, data_source)
@id=computer_id
@data_source=data_source
data_source.methods.grep(/^get_(.)_info$/) { Computer.define_component $1}
end
def self.define_component(name)
define_method(name){
info=@data_source.send "get_#{name}_info", @id
price=@data_source.send "get_#{name}_price", @id
result="#{name.capitalize}:#{info} $#{price}"
return "* #{result}" if price>100
end
end
2 动态代理和白板技术
class Computer
instance_methods.each do |m|
undef_method m unless m.to_s=~/^_|method_missing | respond_to? /
end
def initialize(computer_id, data_source)
@id=computer_id
@data_source=data_source
end
def method_missing(name, *args)
super if !respond_to?(name)
info=@data_source.send "get_#{name}_info", @id
price=@data_source.send "get_#{name}_price", @id
result="#{name.capitalize}:#{info} $#{price}"
return "* #{result}" if price>100
end
def respond_to?(method)
@data_source.respond_to?("get_#{method}_info)" || super
end
end