Wzorzec dekoratora
Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 52 z 65.
Wzorzec Dekorator dodaje zachowanie do obiektu, opakowując go w inny obiekt z tymi samymi metodami. Każda otoczka wywołuje obiekt znajdujący się wewnątrz i dodaje własną część, a otoczki można nakładać na siebie w dowolnej kolejności.
# weapon.gd
class_name Weapon
extends RefCounted
func get_damage() -> int:
return 10
func describe() -> String:
return "Sword"Dekorator rozszerza Weapon, więc można go użyć wszędzie tam, gdzie oczekiwana jest broń, i przechowuje owiniętą przez siebie broń:
# fire_enchant.gd
class_name FireEnchant
extends Weapon
var inner: Weapon
func _init(wrapped: Weapon) -> void:
inner = wrapped
func get_damage() -> int:
return inner.get_damage() + 5
func describe() -> String:
return inner.describe() + " + Fire"SharpEnchant jest zapisany w ten sam sposób, ale jego get_damage() zwraca inner.get_damage() * 2, a jego describe() dodaje " + Sharp".
# main.gd
var weapon: Weapon = Weapon.new()
print(weapon.describe(), ": ", weapon.get_damage())
weapon = FireEnchant.new(weapon)
weapon = SharpEnchant.new(weapon)
print(weapon.describe(), ": ", weapon.get_damage())Sword: 10
Sword + Fire + Sharp: 30Wywołania biegną do wewnątrz: SharpEnchant pyta FireEnchant, który pyta miecz. Miecz zwraca 10, ogień zwiększa tę wartość do 15, a Sharp podwaja ją do 30. W odwrotnej kolejności, FireEnchant.new(SharpEnchant.new(Weapon.new())), obrażenia wynoszą 10 * 2 + 5, czyli 25.
Bez dekoratorów każda kombinacja wymagałaby własnej podklasy: FireSword, SharpSword, FireSharpSword i tak dalej. Dzięki nim dwie małe klasy obsługują każdą kombinację, a nowe zaklęcie to kolejny plik.
Wyzwanie
ŚredniKawiarnia przygotowuje napoje za pomocą dekoratorów. Beverage (beverage.gd) deklaruje cost() i description(); Espresso (espresso.gd, $3) i Tea (tea.gd, $2) są już napisane. Każdy dekorator przechowuje napój, który opakowuje, w inner (konstruktory są już napisane). Nadpisz cost() i description() w:
Milk: kosztuje o1więcej i dodaje+ Milkdo opisu.Mocha: kosztuje o2więcej i dodaje+ Mocha.Large: podwaja koszt wszystkiego, co się w nim znajduje, i umieszczaLargena początku opisu.
Dostarczony kod odczytuje liczbę kolejnych zamówień, a następnie jedno zamówienie w każdym wierszu: napój (espresso lub tea) i dodatki, stosowane od lewej do prawej. Dla espresso milk large i tea mocha milk wynik to:
Large Espresso + Milk: $8
Tea + Mocha + Milk: $5Twój kod umieść w plikach milk.gd, mocha.gd i large.gd. main.gd zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
extends Node
func _ready():
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
var count := int(OS.read_string_from_stdin())
for i in count:
var words := OS.read_string_from_stdin().split(" ")
var drink: Beverage = Tea.new()
if words[0] == "espresso":
drink = Espresso.new()
for extra in words.slice(1):
match extra:
"milk":
drink = Milk.new(drink)
"mocha":
drink = Mocha.new(drink)
"large":
drink = Large.new(drink)
print("%s: $%d" % [drink.description(), drink.cost()])
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe selfMetodyWłaściwościKonstruktor (_init)Powtórka – prosty kalkulator4Polimorfizm
Ponowne omówienie przesłaniania metodDuck typingKlasy i metody abstrakcyjneProjektowanie interfejsówPowtórzenie – kalkulator kształtów7Sygnały
Czym jest sygnał?Deklarowanie i emitowanieŁączenie z sygnałamiSygnały z argumentamiPodsumowanie — system zdrowia10Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu2Właściwości klas
Zmienne instancji a zmienne statyczneFunkcje statyczneSettery właściwościGettery właściwościPrywatne z konwencjiPodsumowanie — menedżer kont bankowych5Enkapsulacja
Elementy publiczne i prywatneWalidacja za pomocą setterówUkrywanie informacjiWłaściwości tylko do odczytuPodsumowanie – system ewidencji uczniów8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieKlasy wewnętrzneWęzły jako komponentyRefCounted a NodeTypy wyliczeniowe w klasach11Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superNadpisywanie metodŁańcuchy dziedziczeniaSprawdzanie typów za pomocą isPodsumowanie – hierarchia pracowników6Metody specjalne
Wprowadzenie do metod wirtualnychMetoda _to_stringWłasne iteratoryPodsumowanie — własna lista9Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator GDScript online