Strategiemuster
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 45 von 57.
Das Strategie-Muster legt einen Teil eines Algorithmus in ein eigenes Objekt und ermöglicht es dem Hauptobjekt, diesen Teil zu delegieren. Das Austauschen der Strategie ändert das Verhalten, ohne die Hauptklasse zu ändern:
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.costAusgabe:
8.0
21Die Strategien teilen sich nur einen Methodennamen, daher funktioniert jedes Objekt mit cost: wieder Duck-Typing. Eine neue Versandmöglichkeit hinzuzufügen bedeutet, eine Klasse hinzuzufügen, nicht einen weiteren Zweig innerhalb von Shipment:
class Pickup
def cost(_kg)
0
end
end
shipment.strategy = Pickup.new # Shipment ist unverändertIn Ruby ist eine Strategie häufig eine Lambda-Funktion. Alles, was auf call reagiert, kann gespeichert und aufgerufen werden, unabhängig davon, ob es sich um eine Lambda-Funktion, ein Methodenobjekt oder ein Objekt deiner eigenen Klasse handelt:
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)Ausgabe:
RUBY IS GREAT
Ruby Is Great
**** is *****Wähle Strategie statt Unterklassen, wenn ein Objekt sein Verhalten während der Programmausführung ändern muss oder wenn die Variation in einem einzelnen Schritt besteht. Eine Unterklasse legt das Verhalten für die gesamte Lebensdauer des Objekts fest:
# Subclassing: bei der Erstellung festgelegt
ExpressShipment.new(2)
# Strategy: kann später geändert werden
shipment = Shipment.new(2, Standard.new)
shipment.strategy = Express.newAufgabe
EinfachVervollständige die Versandstrategien und ShippingCalculator. Standard#cost(kg) beträgt 5 plus 1,50 pro kg, Express#cost(kg) beträgt 15 plus 3 pro kg und Pickup#cost(kg) beträgt 0. Der Rechner wird mit einer Strategie erstellt, kann mit strategy= geändert werden, und quote(kg) gibt 2.5 kg by Express: 22.50 unter Verwendung des Klassennamens der Strategie zurück.
Der bereitgestellte Code beginnt mit Standard und liest die Befehle use express, use pickup, use standard oder quote 2.5 ein und gibt jedes Angebot aus.
Dein Code gehört in standard.rb, express.rb, pickup.rb und shipping_calculator.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
require_relative 'standard'
require_relative 'express'
require_relative 'pickup'
require_relative 'shipping_calculator'
# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
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
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