Wzorzec strategii
Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 45 z 57.
Wzorzec strategii umieszcza jedną część algorytmu we własnym obiekcie i pozwala głównemu obiektowi delegować do niego zadania. Zmiana strategii modyfikuje zachowanie bez zmiany głównej klasy:
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.costWynik:
8.0
21Strategie mają wspólną tylko nazwę metody, więc działa każdy obiekt z cost: znów typowanie kacze. Dodanie nowego sposobu wysyłki oznacza dodanie jednej klasy, a nie kolejnej gałęzi wewnątrz Shipment:
class Pickup
def cost(_kg)
0
end
end
shipment.strategy = Pickup.new # Shipment pozostaje bez zmianW Ruby strategią jest często lambda. Wszystko, co odpowiada na call, można przechować i wywołać, niezależnie od tego, czy jest to lambda, obiekt metody, czy obiekt własnej klasy:
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)Wynik:
RUBY IS GREAT
Ruby Is Great
**** is *****Wybierz strategię zamiast podklas, gdy jeden obiekt musi zmieniać swoje zachowanie podczas działania programu lub gdy zmienność dotyczy jednego kroku. Podklasa ustala zachowanie na cały czas istnienia obiektu:
# dziedziczenie: ustalone przy tworzeniu
ExpressShipment.new(2)
# strategia: można ją później zmienić
shipment = Shipment.new(2, Standard.new)
shipment.strategy = Express.newWyzwanie
ŁatwyUzupełnij strategie wysyłki i ShippingCalculator. Standard#cost(kg) wynosi 5 plus 1.50 za kg, Express#cost(kg) wynosi 15 plus 3 za kg, a Pickup#cost(kg) wynosi 0. Kalkulator jest tworzony ze strategią, można ją zmienić za pomocą strategy=, a quote(kg) zwraca 2.5 kg by Express: 22.50, używając nazwy klasy strategii.
Dostarczony kod rozpoczyna działanie ze strategią Standard i odczytuje polecenia use express, use pickup, use standard lub quote 2.5, wypisując każdą wycenę.
Umieść swój kod w plikach standard.rb, express.rb, pickup.rb i shipping_calculator.rb. Plik main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
require_relative 'standard'
require_relative 'express'
require_relative 'pickup'
require_relative 'shipping_calculator'
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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
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