Delegowanie z Forwardable
Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 46 z 57.
Delegowanie oznacza, że obiekt przekazuje część swojej pracy obiektowi, który zawiera, zamiast po nim dziedziczyć. Playlista zawierająca tablicę utworów jest bezpieczniejsza niż taka, która sama jest tablicą, ponieważ kod zewnętrzny uzyskuje dostęp tylko do metod, które zdecydujesz się przekazać dalej:
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.firstWynik:
2
IntroRęczne pisanie każdej metody przekazującej wywołanie jest powtarzalne. Biblioteka standardowa robi to za pomocą Forwardable: extend Forwardable, a następnie def_delegators :@songs, :size, :first przekazuje te wywołania do obiektu w @songs:
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?Wynik:
2 Intro Dune
true
falsedef_delegator :@songs, :push, :add przekazuje jedną metodę pod nową nazwą. Obiekt zachowuje pełną kontrolę nad wszystkim, czego nie przekazuje, na przykład nad delete lub 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)Wynik:
a
1
falseWybierz delegowanie („ma”) wtedy, gdy klasa potrzebuje tylko części zachowania innej klasy. Dziedziczenie po Array udostępniłoby dziesiątki metod, takich jak clear i delete_at, które mogłyby naruszyć zasady playlisty:
class Playlist < Array # każda metoda Array jest publiczna, w tym clear
end
class Playlist # publiczne jest tylko to, co delegujesz
extend Forwardable
def_delegators :@songs, :size, :each
endWyzwanie
ŁatwyUzupełnij klasę Playlist za pomocą Forwardable. Przechowuje ona utwory w @songs, każdy jako parę [title, seconds]. Przekaż metody size, empty? i first za pomocą def_delegators, a metodę push pod nazwą add za pomocą def_delegator. Jej własna metoda duration zwraca łączny czas trwania w formacie m:ss, a metoda titles zwraca tytuły połączone za pomocą , .
Dostarczony kod dodaje jeden utwór dla każdej linii wejściowej (title,seconds) za pomocą add, a następnie wypisuje rozmiar, pierwszy tytuł, tytuły, czas trwania oraz informację, czy playlista odpowiada na metodę clear.
Umieść swój kod w pliku playlist.rb. Plik main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
require_relative 'playlist'
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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)}"
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasZmienne instancjiMetody i selfto_s i inspectPowtórzenie – karta biblioteczna4Hermetyzacja
Metody prywatneMetody chronionePrywatne setteryOchrona stanuPowtórzenie – automat vendingowy7Polimorfizm i typowanie kacze
PolimorfizmTypowanie kaczeMetody abstrakcyjnecase i klasyPowtórzenie – metody płatności10Wzorce projektowe, część 2
Delegowanie z ForwardableWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Metody dostępowe i self
Gettery i setteryWłasne setteryself w metodachTożsamość i równośćPowtórzenie – lista kontaktów5Dziedziczenie
PodklasyNadpisywanie metodWywoływanie superis_a? i przodkowiePowtórka – lista płac pracowników8Metody specjalne
Równość i hashMetody operatorówIndeksowanie i dodawanieWłasne kolekcjePowtórka – ułamki11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Kompilator Ruby online