Pattern Decorator
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 47 di 57.
Il pattern decorator avvolge un oggetto in un altro oggetto con la stessa interfaccia, che aggiunge qualcosa prima o dopo aver passato la chiamata. I decorator possono essere concatenati in qualsiasi ordine:
class Coffee
def cost
2.0
end
def description
"coffee"
end
end
class Milk
def initialize(drink)
@drink = drink
end
def cost
@drink.cost + 0.5
end
def description
"#{@drink.description}, milk"
end
end
order = Milk.new(Milk.new(Coffee.new))
puts format("%s: %.2f", order.description, order.cost)Output:
coffee, milk, milk: 3.00Ogni decoratore memorizza l'oggetto avvolto e gli inoltra le chiamate, quindi una classe base condivisa può occuparsi di questa parte. Ogni decoratore concreto poi sovrascrive solo ciò che modifica:
class Coffee
def cost
2.0
end
def description
"coffee"
end
end
class Extra
def initialize(drink)
@drink = drink
end
def cost
@drink.cost
end
def description
@drink.description
end
end
class Sugar < Extra
def cost
super + 0.2
end
def description
super + ", sugar"
end
end
order = Sugar.new(Coffee.new)
puts format("%s: %.2f", order.description, order.cost)Output:
coffee, sugar: 2.20La libreria standard SimpleDelegator (require 'delegate') inoltra all'oggetto wrapper ogni metodo che non definisce, mantenendo breti i decorator quando l'interfaccia è ampia:
require 'delegate'
class Loud < SimpleDelegator
def to_s
super.upcase + "!"
end
end
text = Loud.new("hello")
puts text
puts text.size
puts text.start_with?("he")Output:
HELLO!
5
trueI decoratori aggiungono comportamento ai singoli oggetti durante l’esecuzione e possono essere combinati liberamente. Con le sottoclassi, ogni combinazione, come MilkSugarCoffee, richiederebbe una classe propria:
Sugar.new(Milk.new(Coffee.new)) # qualsiasi combinazione, in qualsiasi ordine
Whip.new(Sugar.new(Coffee.new))
# con sottoclassi: MilkCoffee, SugarCoffee, MilkSugarCoffee, ...Sfida
FacileCompleta i decoratori del caffè. Coffee costa 2.00 ed è descritto come coffee. Milk aggiunge 0.50 e , milk, Sugar aggiunge 0.20 e , sugar, e Whip aggiunge 0.70 e , whip. I tre decoratori condividono la classe base Extra, che memorizza la bevanda avvolta e inoltra cost e description; ogni sottoclasse usa super.
Ogni riga di input è un ordine, ad esempio milk sugar. Il codice fornito avvolge un nuovo Coffee nei decoratori in quest'ordine e stampa coffee, milk, sugar: 2.70.
Il tuo codice va in coffee.rb, extra.rb, milk.rb, sugar.rb e whip.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'coffee'
require_relative 'extra'
require_relative 'milk'
require_relative 'sugar'
require_relative 'whip'
# Código de entrada/salida proporcionado: mantenlo tal como está
input = []
while (line = gets)
input << line.chomp
end
extras = { "milk" => Milk, "sugar" => Sugar, "whip" => Whip }
input.each do |line|
drink = line.split.reduce(Coffee.new) { |d, name| extras[name].new(d) }
puts format("%s: %.2f", drink.description, drink.cost)
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