【发布时间】:2009-09-27 02:02:26
【问题描述】:
我正在尝试用 Ruby 编写最安全的单例。我是这门语言的新手,它非常有弹性,以至于我没有强烈的感觉,我的单例课程只会成功创建一个实例。作为奖励,我希望该对象仅在真正使用时才被实例化。
【问题讨论】:
标签: ruby design-patterns singleton
我正在尝试用 Ruby 编写最安全的单例。我是这门语言的新手,它非常有弹性,以至于我没有强烈的感觉,我的单例课程只会成功创建一个实例。作为奖励,我希望该对象仅在真正使用时才被实例化。
【问题讨论】:
标签: ruby design-patterns singleton
# require singleton lib
require 'singleton'
class AppConfig
# mixin the singleton module
include Singleton
# do the actual app configuration
def load_config(file)
# do your work here
puts "Application configuration file was loaded from file: #{file}"
end
end
conf1 = AppConfig.instance
conf1.load_config "/home/khelll/conf.yml"
#=>Application configuration file was loaded from file: /home/khelll/conf.yml
conf2 = AppConfig.instance
puts conf1 == conf2
#=>true
# notice the following 2 lines won’t work
AppConfig.new rescue(puts $!)
#=> new method is private
# dup won’t work
conf1.dup rescue(puts $!)
#=>private method `new’ called for AppConfig:Class
#=>can’t dup instance of singleton AppConfig
那么当你在你的类中包含单例模块时,ruby 会做什么呢?
new 方法设为私有,因此您无法使用它。所以要使用 ruby 单例模块,你需要两件事:
singleton 然后将其包含在所需的类中。instance 方法获取您需要的实例。【讨论】:
如果你想创建一个单例,为什么还要创建一个类呢?只需创建一个对象,然后添加所需的方法和实例变量即可。
>> MySingleton = Object.new
=> #<Object:0x100390318>
>> MySingleton.instance_eval do
?> @count = 0
>> def next
>> @count += 1
>> end
>> end
=> nil
>> MySingleton.next
=> 1
>> MySingleton.next
=> 2
>> MySingleton.next
=> 3
人们实现此模式的更标准方法是使用Module 作为单例对象(而不是更通用的Object):
>> module OtherSingleton
>> @index = -1
>> @colors = %w{ red green blue }
>> def self.change
>> @colors[(@index += 1) % @colors.size]
>> end
>> end
=> nil
>> OtherSingleton.change
=> "red"
>> OtherSingleton.change
=> "green"
>> OtherSingleton.change
=> "blue"
>> OtherSingleton.change
=> "red"
如果您希望您的单例对象从某个类继承,只需将其设为该类的实例即可。要从 mixin 继承,只需使用 #extend。如果你想要一个单例对象,ruby 让它变得非常容易,而且与其他语言不同,它不必在类中定义。
临时单例(我的第一个示例)无处不在,涵盖了我遇到的大多数情况。模块技巧通常涵盖其余部分(当我想要更正式的东西时)。
Ruby 代码应该(恕我直言)使用鸭子类型(通过#respond_to?)而不是显式检查对象的类,所以我通常不关心我的单例对象类的唯一性,因为它不是它的类它是独一无二的,但我之后添加的所有内容。
【讨论】:
require 'singleton'
class Klass
include Singleton
# ...
end
【讨论】: