Когда разумно использовать классы Singleton в Ruby?
Я читал о Singletons в Ruby. Мне никогда не приходилось использовать их раньше, но мне стало любопытно и решили посмотреть их, посмотреть, следует ли мне использовать их в прошлом, или, может быть, я смогу использовать их в будущем, если бы я знал, используется для.
Единственное, что я могу использовать, это:
- ? Когда мне нужен специальный объект. Пример: "умный"
Hash
объект, который действует как обычный рубиновый хэш с несколькими дополнительными причудами.
- Когда я хочу сделать так, может существовать только один экземпляр класса.
Тем не менее, я не уверен, что мне нужно было либо из вышеперечисленного.
Ответы
Ответ 1
Обратите внимание, что смешивание классов в модуле Singleton функционально эквивалентно классу или модулю с методами класса и либо гарантированному вызову инициализации, либо встроенной инициализации. Сравните это использование Singleton:
require 'singleton'
class Bar
include Singleton
attr_reader :jam
def initialize
@jam = 42
end
def double
@jam *= 2
end
end
b1 = Bar.instance
b1.double
b2 = Bar.instance
b2.double
p b1.jam #=> 168
с этим не магическим модулем:
module Foo
@jam = 42
def self.double
@jam *= 2
end
def self.jam
@jam
end
end
Foo.double
Foo.double
p Foo.jam #=> 168
В обоих случаях у вас есть один глобальный объект, который поддерживает состояние. (Поскольку каждая константа, которую вы создаете в глобальной области, включая классы и модули, является глобальным объектом.)
Единственное функциональное отличие заключается в том, что с Singleton
вы задерживаете инициализацию объекта до первого запроса.
Итак, если у вас когда-либо были методы класса в классе или модуле, и вы используете их для изменения состояния этого объекта (например, класс, отслеживающий все подклассы, которые наследуются от него), вы по существу используете одноэлемент.
Ответ 2
В Ruby вы используете классы singleton все время. Фактически, каждый объект имеет одноэлементный класс. (Примечание: по соображениям производительности одноэлементные классы фактически создаются только при первом доступе к ним, но в том, что оптимизация производительности. Семантически каждый раз, когда вы пытаетесь взглянуть на одноэлементный класс, он будет там.)
Так называемые "методы класса", например, фактически не существуют в Ruby. Это просто обычные методы экземпляра класса singleton class. (Вместо этого просто проще сказать "метод класса".)
Каждый раз, когда вы определяете метод с синтаксисом def foo.bar
, вы добавляете метод к одиночному классу foo
.
Ответ 3
Как вы сказали, класс Singleton необходим, когда вам нужно иметь только один экземпляр класса. Очень хорошим примером класса Singleton в общепринятой структуре является класс Rails Logger.
Ответ 4
Ваша вторая точка маркера точно соответствует точке. подумайте о одиночном классе как о полностью статическом объекте. Булевы и Нулевые объекты в рубине являются примерами.