Singleton-Muster
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 42 von 57.
Ein Entwurfsmuster ist eine bewährte Lösung für ein häufig auftretendes Entwurfsproblem. Das Singleton-Muster stellt sicher, dass eine Klasse genau eine Instanz besitzt, die von überall aus erreichbar ist. Rubys Standardbibliothek hat es integriert: require 'singleton' und include Singleton fügen eine Klassenmethode instance hinzu:
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)Ausgabe:
dark
trueinclude Singleton macht außerdem new privat, sodass keine zweite Instanz erstellt werden kann. Jeder Teil des Programms, der nach instance fragt, erhält dasselbe Objekt:
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
endAusgabe:
3
private method `new' called for class CounterDieselbe Idee von Hand geschrieben ist eine Klassenmethode, die die Instanz bei der ersten Verwendung erstellt, sowie ein privates new. Dies zeigt, was das Modul für dich übernimmt:
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.levelAusgabe:
3Verwende Singleton-Objekte sparsam. Ein Singleton ist ein globaler Zustand: Jeder Code kann ihn ändern, und Tests können nicht mit einer sauberen Kopie starten. Sie eignen sich für Dinge, die wirklich nur einmal pro Programm existieren, etwa einen Logger oder die Konfiguration; ein Objekt als Parameter zu übergeben, ist oft klarer:
# einfacher zu testen: der Logger wird übergeben
def process(order, log)
log.write("processing #{order.id}")
endAufgabe
EinfachVervollständige das Singleton AppLogger mit include Singleton. Es verwaltet ein Array von Einträgen und verfügt über log(message, level), das [INFO] message oder [ERROR] message (die Ebene in Großbuchstaben), entries und error_count speichert. Die Hilfsfunktionen handle_info(message) und handle_error(message) in functions.rb protokollieren beide über AppLogger.instance, sodass sie dasselbe Objekt erreichen.
Der bereitgestellte Code liest Zeilen im Format info,message oder error,message, leitet sie über die Hilfsfunktionen weiter, gibt jeden Eintrag und errors: 1 aus und überprüft, dass AppLogger.new abgelehnt wird.
Dein Code gehört in app_logger.rb und functions.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
require_relative 'app_logger'
require_relative 'functions'
# Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
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
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenInstanzvariablenMethoden und selfto_s und inspectRückblick – Bibliotheksausweis4Kapselung
Private MethodenGeschützte MethodenPrivate SetterZustand schützenRückblick – Verkaufsautomat7Polymorphismus und Duck Typing
PolymorphismusDuck TypingAbstrakte MethodenFälle und KlassenRückblick – Zahlungsmethoden2Getter und Setter sowie self
Leser und SchreiberBenutzerdefinierte Setterself in MethodenIdentität und GleichheitWiederholung – Kontaktliste5Vererbung
UnterklassenMethoden überschreibensuper aufrufenis_a? und VorfahrenRückblick – Gehaltsabrechnung des Personals8Spezielle Methoden
Gleichheit und HashOperator-MethodenIndexieren und AnhängenBenutzerdefinierte CollectionsRückblick – Brüche11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-Ruby-Compiler