модуль Singleton
Модуль Singleton реализует паттерн Singleton.
Использование
Для использования Singleton, включите модуль в свой класс.
class Klass include Singleton # ... end
Это гарантирует, что будет создан только один экземпляр класса Klass.
a,b = Klass.instance, Klass.instance a == b # => true Klass.new # => NoMethodError - new is private ...
Экземпляр создается при первом вызове Klass.instance().
class OtherKlass
include Singleton
# ...
end
ObjectSpace.each_object(OtherKlass){}
# => 0
OtherKlass.instance
ObjectSpace.each_object(OtherKlass){}
# => 1
Это поведение сохраняется при наследовании и клонировании.
Реализация
Это достигается следующим:
-
Сделайте Klass.new и Klass.allocate закрытыми.
-
Переопределите Klass.inherited(sub_klass) и Klass.clone(), чтобы гарантировать, что свойства
Singletonсохраняются при наследовании и клонировании. -
Предоставьте метод Klass.instance(), который возвращает один и тот же объект каждый раз, когда он вызывается.
-
Переопределите Klass._load(str), чтобы вызвать Klass.instance().
-
Переопределите Klass#clone и Klass#dup, чтобы вызывать TypeErrors, предотвращая клонирование или дублирование.
Singleton и Marshal
По умолчанию _dump(depth) Singleton возвращает пустую строку. Маршаллинг по умолчанию удалит информацию о состоянии, например, переменные экземпляра из экземпляра. Классы, использующие Singleton, могут предоставить пользовательские методы _load(str) и _dump(depth), чтобы сохранить часть предыдущего состояния экземпляра.
require 'singleton'
class Example
include Singleton
attr_accessor :keep, :strip
def _dump(depth)
# this strips the @strip information from the instance
Marshal.dump(@keep, depth)
end
def self._load(str)
instance.keep = Marshal.load(str)
instance
end
end
a = Example.instance
a.keep = "keep this"
a.strip = "get rid of this"
stored_state = Marshal.dump(a)
a.keep = nil
a.strip = nil
b = Marshal.load(stored_state)
p a == b # => true
p a.keep # => "keep this"
p a.strip # => nil
Константы
- VERSION
Открытые методы класса
# File lib/singleton.rb, line 171
По умолчанию вызывает instance(). Переопределите для сохранения состояния синглтона.
# File lib/singleton.rb, line 175
Возвращает экземпляр синглтона.
Закрытые методы класса
# File lib/singleton.rb, line 154
def append_features(mod)
# help out people counting on transitive mixins
unless mod.instance_of?(Class)
raise TypeError, "Inclusion of the OO-Singleton module in module #{mod}"
end
super
end # File lib/singleton.rb, line 162 def included(klass) super klass.private_class_method :new, :allocate klass.extend SingletonClassMethods Singleton.__init__(klass) end
Открытые методы экземпляра
# File lib/singleton.rb, line 108 def _dump(depth = -1) '' end
По умолчанию не сохраняет состояние при маршаллировании.
# File lib/singleton.rb, line 98
def clone
raise TypeError, "can't clone instance of singleton #{self.class}"
end Вызывает TypeError для предотвращения клонирования.
# File lib/singleton.rb, line 103
def dup
raise TypeError, "can't dup instance of singleton #{self.class}"
end Вызывает TypeError для предотвращения дублирования.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.