混入Singleton,就省略了创建类变量,初始化单例实例,创建类级别的instance方法,以及将new设为私有。
通过SimpleLogger.instance来获取日志器的单例。
但是两种方式还是又差异的。
第一种方式称之为“勤性单例(eager instantiation)”。
在确实需要之前就创建了实例对象。
第二种方式称之为“惰性单例(lazy instantiation)”
在调用instance时才会去创建 。
但是这个Singleton不能真正的阻止任何事情,可以用过public_class_method改变new方法的为公用的。
打开类,设置new方法为public之后,就可以用SimpleLogger.new来创建对象了。
class SimpleLogger public_class_method :new end puts SimpleLogger.new
再来分两种情况:
(一)使用全局变量,尽量不要使用全局变量,因为全局变量是程序紧密的耦合在一起,
其实单例模式和全局变量的作用是一样的,
$logger = SimpleLogger.new
(二)使用类作为单例,
class SimpleLogger
WARNING = 1
INFO = 2
def initialize(file)
@@log = File.open(file, "w")
@@level = WARNING
end
def self.warning(msg)
puts @@level > WARNING
@@log.puts(msg) if @@level > WARNING
@@log.flush
end
def self.level
@@level
end
def self.level=(new_level)
@@level = new_level
end
end
SimpleLogger.new("test.txt")
puts SimpleLogger.level
SimpleLogger.level = SimpleLogger::INFO
puts SimpleLogger.level
SimpleLogger.warning("warning")
实例
require 'rubygems'
require 'watir'
require 'singleton'
class AutoTest
include Singleton
def OpenUrl(url)
@browser= Watir::Browser.new
@browser.goto(url)
@url=url
end
def set_textarea(text)
@browser.text_field(:id,'kw').set(text)
end
def click
@browser.button(:id,'su').click
end
end
test,test2 = AutoTest.instance
test.OpenUrl('http://www.baidu.com')
test.set_textarea('aslandhu')
test.click
这里虽然创建了两个AutoTest实例,但是第二个实例其实为nil,也就是说并没有创建成功。
require 'rubygems'
require 'watir'
require 'singleton'
require 'thread'
class TestOneObj
end
class <<TestOneObj
include Singleton
def instance
@browser= Watir::Browser.new
self
end
def openurl(url)
@browser.goto(url)
end
def set_textarea(text)
@browser.text_field(:id,'kw').set(text)
end
def click
@browser.button(:id,'su').click
end
end
test = TestOneObj.instance
test2 = TestOneObj.instance
p test.inspect
p test2.inspect
test.openurl('www.baidu.com')
test2.set_textarea('aslandhu')
test.click
上面这段代码试图创建两个Browser对象,但事实上创建的两个对象均为同一个。虽然打开了两个IE窗口,但是对象还是一个,即test与test2是同一个对象。










