Pattern Singleton
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 42 di 57.
Un design pattern è una soluzione collaudata a un problema di progettazione comune. Il pattern singleton assicura che una classe abbia esattamente un’istanza, accessibile da qualsiasi punto. La libreria standard di Ruby lo include già: require 'singleton' e include Singleton aggiungono il metodo di classe instance:
require 'singleton'
class Settings
include Singleton
attr_accessor :theme
def initialize
@theme = "light"
end
end
Settings.instance.theme = "dark"
puts Settings.instance.theme
puts Settings.instance.equal?(Settings.instance)Output:
dark
trueinclude Singleton rende anche new privato, così non è possibile creare una seconda istanza. Ogni parte del programma che richiede instance ottiene lo stesso oggetto:
require 'singleton'
class Counter
include Singleton
attr_reader :hits
def initialize
@hits = 0
end
def hit
@hits += 1
end
end
def page_a
Counter.instance.hit
end
def page_b
2.times { Counter.instance.hit }
end
page_a
page_b
puts Counter.instance.hits
begin
Counter.new
rescue NoMethodError => e
puts e.message
endOutput:
3
private method `new' called for class CounterLa stessa idea scritta a mano consiste in un metodo di classe che crea l’istanza al primo utilizzo e in un new privato. Ecco cosa fa il modulo per te:
class Config
def self.instance
@instance ||= new
end
private_class_method :new
attr_accessor :level
def initialize
@level = 1
end
end
Config.instance.level = 3
puts Config.instance.levelOutput:
3Usa i singleton con parsimonia. Un singleton è uno stato globale: qualsiasi codice può modificarlo e i test non possono partire da una copia pulita. Sono adatti a elementi che esistono davvero una sola volta per programma, come un logger o la configurazione; spesso è più chiaro passare un oggetto come parametro:
# più facile da testare: il logger viene passato come argomento
def process(order, log)
log.write("processing #{order.id}")
endSfida
FacileCompleta il singleton AppLogger con include Singleton. Mantiene un array di voci e dispone di log(message, level), che memorizza [INFO] message oppure [ERROR] message (il livello in maiuscolo), entries e error_count. Gli helper handle_info(message) e handle_error(message) in functions.rb registrano entrambi tramite AppLogger.instance, quindi raggiungono lo stesso oggetto.
Il codice fornito legge righe info,message o error,message, le invia tramite gli helper, stampa ogni voce e errors: 1, e verifica che AppLogger.new venga rifiutato.
Il tuo codice va in app_logger.rb e functions.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'app_logger'
require_relative 'functions'
# Codice di input/output fornito: lascialo così com'è
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
level, message = line.split(",", 2)
level == "error" ? handle_error(message) : handle_info(message)
end
AppLogger.instance.entries.each { |e| puts e }
puts "errors: #{AppLogger.instance.error_count}"
begin
AppLogger.new
puts "new is allowed"
rescue NoMethodError
puts "new is private"
end
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libriEsercitati da solo: Compilatore Ruby online