Pattern Strategy
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 45 di 57.
Il pattern strategy inserisce una parte di un algoritmo in un proprio oggetto e permette all'oggetto principale di delegare a esso. Sostituire la strategia cambia il comportamento senza modificare la classe principale:
class Standard
def cost(kg)
5 + kg * 1.5
end
end
class Express
def cost(kg)
15 + kg * 3
end
end
class Shipment
attr_writer :strategy
def initialize(kg, strategy)
@kg = kg
@strategy = strategy
end
def cost
@strategy.cost(@kg)
end
end
s = Shipment.new(2, Standard.new)
puts s.cost
s.strategy = Express.new
puts s.costOutput:
8.0
21Le strategie condividono solo il nome di un metodo, quindi qualsiasi oggetto con cost funziona: ancora una volta, duck typing. Aggiungere un nuovo modo di spedire significa aggiungere una classe, non un altro ramo all'interno di Shipment:
class Pickup
def cost(_kg)
0
end
end
shipment.strategy = Pickup.new # Shipment rimane invariatoIn Ruby una strategia è spesso una lambda. Qualsiasi cosa risponda a call può essere memorizzata e invocata, che sia una lambda, un oggetto metodo o un oggetto di una classe definita da te:
class TextFormatter
def initialize(strategy)
@strategy = strategy
end
def format_all(words)
words.map { |w| @strategy.call(w) }.join(" ")
end
end
class Censor
def call(word)
word.size > 3 ? "*" * word.size : word
end
end
words = %w[ruby is great]
puts TextFormatter.new(->(w) { w.upcase }).format_all(words)
puts TextFormatter.new(:capitalize.to_proc).format_all(words)
puts TextFormatter.new(Censor.new).format_all(words)Output:
RUBY IS GREAT
Ruby Is Great
**** is *****Scegli la strategia invece delle sottoclassi quando un oggetto deve cambiare comportamento mentre il programma è in esecuzione, oppure quando la variazione riguarda un singolo passaggio. Una sottoclasse fissa il comportamento per tutta la vita dell'oggetto:
# creazione di sottoclassi: fissata alla creazione
ExpressShipment.new(2)
# strategia: può cambiare in seguito
shipment = Shipment.new(2, Standard.new)
shipment.strategy = Express.newSfida
FacileCompleta le strategie di spedizione e ShippingCalculator. Standard#cost(kg) è 5 più 1.50 per kg, Express#cost(kg) è 15 più 3 per kg e Pickup#cost(kg) è 0. Il calcolatore viene creato con una strategia, può cambiarla con strategy= e quote(kg) restituisce 2.5 kg by Express: 22.50, usando il nome della classe della strategia.
Il codice fornito inizia con Standard e legge i comandi use express, use pickup, use standard o quote 2.5, stampando ogni preventivo.
Il tuo codice va in standard.rb, express.rb, pickup.rb e shipping_calculator.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'standard'
require_relative 'express'
require_relative 'pickup'
require_relative 'shipping_calculator'
# Codice di input/output fornito: lascialo così com'è
input = []
while (line = gets)
input << line.chomp
end
strategies = { "standard" => Standard, "express" => Express, "pickup" => Pickup }
calc = ShippingCalculator.new(Standard.new)
input.each do |line|
cmd, arg = line.split
if cmd == "use"
calc.strategy = strategies[arg].new
else
puts calc.quote(arg.to_f)
end
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