Ruby中的IoC容器:needle

來源:互聯網
上載者:User
     作者 liubin   http://www.ruby-cn.org/
     IoC(Inversion of Control),也就是中文所說的控制反轉,有時候也叫做DI(Dependency Injection),即依賴注射。在JAVA中,這樣的容器不少,比如Spring。Ruby中也存在這樣的容器,比如needle和Copland,這兩個作品的作者都是Jamis Buck 。關於什麼是DI/IoC,可以參看經典文章:Martin Fowler的Inversion of Control and the Dependency Injection Pattern。
    特點:
  • 支援Type 2 (Setter) 和Type 3 (Constructor)的注射方式
  • 為服務方法提供AOP的鉤子實現攔截
  • 分層的命名空間
  • 生命週期管理(延遲初始化,單例模式等)

    一個例子:
   cacl.rb
  module Calculator

  class Adder
    def compute( a, b )
      a.to_f + b.to_f
    end
  end

  class Subtractor
    def compute( a, b )
      a.to_f - b.to_f
    end
  end

  class Multiplier
    def compute( a, b )
      a.to_f * b.to_f
    end
  end

  class Divider
    def compute( a, b )
      a.to_f / b.to_f
    end
  end

  class Sine
    def compute( a )
      Math.sin( a )
    end
  end

  class Calculator
    def initialize( operations )
      @operations = operations
    end

    def method_missing( op, *args )
      if @operations.has_key?(op)
        @operations[op].compute( *args )
      else
        super
      end
    end

    def respond_to?( op )
      @operations.has_key?(op) or super
    end
  end

  def register_services( registry )
    registry.namespace! :calc do
      namespace! :operations do
        add      { Adder.new      }
        subtract { Subtractor.new }
        multiply { Multiplier.new }
        divide   { Divider.new    }
        sin      { Sine.new       }
      end

      calculator { Calculator.new( operations ) }
    end
  end
  module_function :register_services

end

上面的類是一些實作類別,可以被下面代碼調用:
require 'needle'
require 'calc'

reg = Needle::Registry.new
Calculator.register_services( reg )

reg.calc.define! do
  intercept( :calculator ).
    with! { logging_interceptor }.
    with_options( :exclude=>%w{divide multiply add} )

  $add_count = 0
  operations.intercept( :add ).
    doing do |chain,ctx|
      $add_count += 1
      chain.process_next( ctx )
    end
end

calc = reg.calc.calculator

puts "add(8,5):      #{calc.add( 8, 5 )}"
puts "subtract(8,5): #{calc.subtract( 8, 5 )}"
puts "multiply(8,5): #{calc.multiply( 8, 5 )}"
puts "divide(8,5):   #{calc.divide( 8, 5 )}"
puts "sin(pi/3):     #{calc.sin( Math::PI/3 )}"
puts "add(1,-6):     #{calc.add( 1, -6 )}"

puts
puts "'add' invoked #{$add_count} times"

參考資料:
1.Needle首頁:http://needle.rubyforge.org
2.Dependency Injection in Ruby :http://onestepback.org/index.cgi/Tech/Ruby/DependencyInjectionInRuby.rdoc

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.