ruby元编程 消除重复代码

    在日常编程中经常无意中会写很多相同或类似的代码,让整个项目代码看起来很难看也不好维护,我们了遵守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

     

      

   


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值