Delegation mit Forwardable
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 46 von 57.
Delegation bedeutet, dass ein Objekt einen Teil seiner Arbeit an ein Objekt übergibt, das es enthält, anstatt von ihm zu erben. Eine Playlist, die ein Array von Songs enthält, ist sicherer als eine, die selbst ein Array ist, da externer Code nur Zugriff auf die Methoden erhält, die du weiterleitest:
class Playlist
def initialize
@songs = []
end
def add(song)
@songs << song
self
end
def size
@songs.size
end
def first
@songs.first
end
end
list = Playlist.new.add("Intro").add("Dune")
puts list.size
puts list.firstAusgabe:
2
IntroJede Weiterleitungsmethode von Hand zu schreiben, ist repetitiv. Die Standardbibliothek übernimmt das mit Forwardable: extend Forwardable, anschließend leitet def_delegators :@songs, :size, :first diese Aufrufe an das Objekt in @songs weiter:
require 'forwardable'
class Playlist
extend Forwardable
def_delegators :@songs, :size, :first, :last, :empty?, :include?
def initialize
@songs = []
end
def add(song)
@songs << song
self
end
end
list = Playlist.new.add("Intro").add("Dune")
puts "#{list.size} #{list.first} #{list.last}"
puts list.include?("Dune")
puts list.empty?Ausgabe:
2 Intro Dune
true
falsedef_delegator :@songs, :push, :add leitet eine Methode unter einem neuen Namen weiter. Das Objekt behält die vollständige Kontrolle über alles, was es nicht weiterleitet, zum Beispiel delete oder clear:
require 'forwardable'
class Queue2
extend Forwardable
def_delegator :@jobs, :push, :enqueue
def_delegator :@jobs, :shift, :next_job
def_delegators :@jobs, :size
def initialize
@jobs = []
end
end
q = Queue2.new
q.enqueue("a")
q.enqueue("b")
puts q.next_job
puts q.size
puts q.respond_to?(:clear)Ausgabe:
a
1
falseBevorzuge Delegation („has a“), wenn eine Klasse nur einen Teil des Verhaltens einer anderen Klasse benötigt. Von Array zu erben würde Dutzende von Methoden verfügbar machen, etwa clear und delete_at, die die Regeln der Playlist verletzen könnten:
class Playlist < Array # jede Array-Methode ist öffentlich, einschließlich clear
end
class Playlist # nur was du weiterleitest ist öffentlich
extend Forwardable
def_delegators :@songs, :size, :each
endAufgabe
EinfachVervollständige die Klasse Playlist mit Forwardable. Sie enthält Lieder, jeweils ein [title, seconds]-Paar, in @songs. Leite size, empty? und first mit def_delegators weiter und leite push unter dem Namen add mit def_delegator weiter. Ihre eigene Methode duration gibt die Gesamtlänge als m:ss zurück, und titles gibt die durch , verbundenen Titel zurück.
Der bereitgestellte Code fügt pro Eingabezeile (title,seconds) mit add ein Lied hinzu und gibt anschließend die Größe, den ersten Titel, die Titel, die Dauer und aus, ob die Playlist auf clear reagiert.
Dein Code gehört in playlist.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
require_relative 'playlist'
# Bereitgestellter Ein-/Ausgabecode: belasse ihn wie er ist
input = []
while (line = gets)
input << line.chomp
end
list = Playlist.new
input.each do |line|
title, seconds = line.split(",")
list.add([title, seconds.to_i])
end
puts "songs: #{list.size}"
puts "first: #{list.empty? ? "none" : list.first[0]}"
puts "titles: #{list.titles}"
puts "duration: #{list.duration}"
puts "can clear: #{list.respond_to?(:clear)}"
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