Wzorzec budowniczego
Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 48 z 57.
Wzorzec budowniczego tworzy złożony obiekt krok po kroku. Każdy krok jest metodą, która zapisuje jeden wybór i zwraca budowniczego, dzięki czemu kroki można łączyć; build sprawdza wybory i zwraca gotowy obiekt:
class Pizza
def initialize(size, toppings)
@size = size
@toppings = toppings
end
def to_s
"#{@size} pizza with #{@toppings.join(", ")}"
end
end
class PizzaBuilder
def initialize
@toppings = []
end
def size(value)
@size = value
self
end
def topping(name)
@toppings << name
self
end
def build
raise ArgumentError, "size is required" if @size.nil?
Pizza.new(@size, @toppings)
end
end
puts PizzaBuilder.new.size("large").topping("cheese").topping("ham").buildWynik:
large pizza with cheese, hamPonieważ kreator tworzy obiekt dopiero w metodzie build, może sprawdzić całą kombinację naraz, na przykład obecność wymaganego elementu albo dwóch opcji, które nie mogą występować razem:
class TicketBuilder
def seat(value)
@seat = value
self
end
def standing
@standing = true
self
end
def build
raise ArgumentError, "seat and standing exclude each other" if @seat && @standing
@standing ? "standing ticket" : "ticket for seat #{@seat || "any"}"
end
end
puts TicketBuilder.new.seat("B7").build
puts TicketBuilder.new.standing.build
begin
TicketBuilder.new.seat("A1").standing.build
rescue ArgumentError => e
puts e.message
endWynik:
ticket for seat B7
standing ticket
seat and standing exclude each otherW języku Ruby często przekazuje się obiekt budujący do bloku. Metoda klasowa tworzy obiekt budujący, przekazuje go do bloku i na końcu wywołuje build:
class Email
attr_accessor :to, :subject, :lines
def self.compose
email = new
email.lines = []
yield email
email
end
def to_s
"To: #{to}\nSubject: #{subject}\n\n#{lines.join("\n")}"
end
end
mail = Email.compose do |e|
e.to = "ada@x.io"
e.subject = "Hi"
e.lines << "Hello Ada,"
e.lines << "see you soon."
end
puts mailWynik:
To: ada@x.io
Subject: Hi
Hello Ada,
see you soon.W przypadku kilku opcjonalnych wartości często wystarczą argumenty nazwane w Ruby z wartościami domyślnymi. Wzorzec budowniczego sprawdza się, gdy elementy mogą się powtarzać, kolejność ma znaczenie albo kombinację trzeba sprawdzić przed utworzeniem obiektu:
Pizza.new(size: "large", crust: "thin") # kilka opcji: argumenty nazwane
Query.new.from("users").where("age > 18").where("active = 1").limit(10).to_sWyzwanie
ŁatwyUzupełnij PizzaBuilder i Pizza. Kroki kreatora size(value), crust(value) i topping(name) (który można powtarzać) zwracają kreator. build zgłasza ArgumentError z komunikatem size is required, jeśli nie podano rozmiaru, używa ciasta classic, jeśli nie wybrano innego, i zwraca obiekt Pizza. Pizza#to_s zwraca large thin pizza with cheese, ham lub small classic pizza with no toppings.
Każdy wiersz wejściowy to jedno zamówienie, na przykład size=large crust=thin topping=cheese topping=ham. Dostarczony kod przekazuje każdą część do kreatora po kolei, łańcuchowo, i wypisuje pizzę lub komunikat o błędzie.
Twój kod umieść w plikach pizza.rb i pizza_builder.rb. main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
require_relative 'pizza'
require_relative 'pizza_builder'
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
builder = line.split.reduce(PizzaBuilder.new) do |b, part|
step, value = part.split("=")
b.public_send(step, value)
end
begin
puts builder.build
rescue ArgumentError => e
puts e.message
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