在日常编程中经常无意中会写很多相同或类似的代码,让整个项目代码看起来很难看也不好维护,我们了遵守Don’t Repeat Yourself(不要重复你自己)原则,在可以的前提下尽可能的抽取相同的代码重复得用。 除了这样,也可以使用ruby元编程技巧解决重复问题,有两种方法 1.动态方法与动态派发; 2.动态代理。
class Ds
def get_mouse_info
puts "a mouse info "
end
def get_cpu_info
puts "a cpu inof "
end
def get_keyboard_info
puts "a keyboard info "
end
end
上面这个类中定义了电脑配件的相应信息,现在要想获得各配件信息定义类如下:
class Computer
def initialize(data_source)
@data_source = data_source
end
def mouse
@data_source.get_mouse_info
end
def keyboard
@data_source.get_keyboard_info
end
def cpu
@data_source.get_cpu_info
end
require "Ds"
computer = Computer.new(Ds.new)
computer.mouse
computer.keyboard
computer.cpu
-> a mouse info
-> a keyboard info
-> a cpu info
从上面代码可以看出代码相似代码重复比较多,哪要怎么消除重复呢?
一、动态方法与动态派发
动态派发: 通过使用send()方法,你想调用的方法名可以作为参数,这样就可以在代码运行期间,直到最后一刻才调用哪个方法。这种技术称为动态派发。
动态方法: 在运行时定义方法的技术(可能通过通用Module#define_method()方法实现),这种技术称为动态方法
class Computer
def initialize(data_source)
@data_source = data_source
end
def self.define_computer_method(method_name)
define_method method_name do
@data_source.send("get_#{method_name.to_s}_info")
end
end
define_computer_method :mouse
define_computer_method :keyboard
define_computer_method :cpu
end
require "Ds"
computer = Computer.new(Ds.new)
computer.mouse
computer.keyboard
computer.cpu
-> a mouse info
-> a keyboard info
-> a cpu info此方法定义了一个类方法 define_computer_method 以要调用方法名为参数,类方法中使用 define_method动态生成想应方法,然后使用动态派发技术调用想应的get_xx_info方法。这相看上去是不是要简单很多。
二、动态代理
动态代理:一个捕获幽灵方法(method_missing())调用并把它们转发给别一个对象的对象,称为动态代理。
class Computer
#使Computer类成为一个白板类
instance_methods.each do |m
undef_method m unless m.to_s =~ /_|method_missing|respond_to?/
end
def initialize(data_source)
@data_source = data_source
end
def method_missing(method)
super if @data_source.respond_to?("#{method.to_s}")
puts "a missing method"
@data_source.send("get_#{method.to_s}_info")
end
def respond_to?(method)
@data_source.respond_to?("get_#{method}_info") || super
end
end
require "Ds"
computer = Computer.new(Ds.new)
computer.mouse
computer.keyboard
computer.cpu
-> a mouse info
-> a keyboard info
-> a cpu info