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 überträgt, das es enthält, anstatt von diesem zu erben. Eine Playlist, die ein Array von Songs enthält, ist sicherer als eine, die selbst ein Array ist, denn externer Code erhält nur Zugriff auf die Methoden, 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 erledigt das mit Forwardable: Mit extend Forwardable und anschließend def_delegators :@songs, :size, :first werden diese Aufrufe an das Objekt in @songs weitergeleitet:
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 volle 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 („hat ein“), wenn eine Klasse nur einen Teil des Verhaltens einer anderen Klasse benötigt. Die Ableitung von Array würde Dutzende von Methoden wie clear und delete_at verfügbar machen, die die Regeln der Playlist verletzen könnten:
class Playlist < Array # jede Methode von Array ist öffentlich, einschließlich clear
end
class Playlist # nur das, was du weiterleitest, ist öffentlich
extend Forwardable
def_delegators :@songs, :size, :each
endAufgabe
EinfachVervollständige die Klasse Playlist mit Forwardable. Sie enthält Songs, jeweils ein Paar aus [title, seconds], in @songs. Delegiere size, empty? und first mit def_delegators weiter und delegiere push unter dem Namen add mit def_delegator. Ihre eigene Methode duration gibt die Gesamtdauer als m:ss zurück, und titles gibt die Titel zurück, verbunden durch , .
Der bereitgestellte Code fügt für jede Eingabezeile (title,seconds) mit add einen Song hinzu und gibt dann die Anzahl, 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 kann nicht bearbeitet werden.
Probier es selbst
require_relative 'playlist'
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
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