Pattern Decorator
Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 52 di 65.
Il pattern Decorator aggiunge comportamento a un oggetto racchiudendolo in un altro oggetto con gli stessi metodi. Ogni wrapper chiama l'oggetto al suo interno e aggiunge la propria parte, e i wrapper possono essere impilati in qualsiasi ordine.
# weapon.gd
class_name Weapon
extends RefCounted
func get_damage() -> int:
return 10
func describe() -> String:
return "Sword"Un decoratore estende Weapon, quindi può essere usato ovunque sia previsto un'arma e contiene l'arma che avvolge:
# 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 è scritto allo stesso modo, ma il suo get_damage() restituisce inner.get_damage() * 2 e il suo describe() aggiunge " + 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: 30Le chiamate procedono verso l'interno: SharpEnchant interroga FireEnchant, che interroga la spada. La spada restituisce 10, il fuoco lo porta a 15 e l'incantesimo affilato lo raddoppia a 30. Nell'altro ordine, FireEnchant.new(SharpEnchant.new(Weapon.new())), il danno è 10 * 2 + 5, cioè 25.
Senza i decoratori, ogni combinazione richiederebbe una propria sottoclasse: FireSword, SharpSword, FireSharpSword e così via. Con essi, due piccole classi coprono ogni combinazione, e un nuovo incantesimo richiede un altro file.
Sfida
MedioUna caffetteria prepara bevande con i decorator. Beverage (beverage.gd) dichiara cost() e description(); sono già scritte Espresso (espresso.gd, $3) e Tea (tea.gd, $2). Ogni decorator memorizza in inner la bevanda che avvolge (i costruttori sono già scritti). Esegui l’override di cost() e description() in:
Milk: costa1in più e aggiunge+ Milkalla descrizione.Mocha: costa2in più e aggiunge+ Mocha.Large: raddoppia il costo di tutto ciò che contiene e metteLargeall’inizio della descrizione.
Il codice fornito legge il numero di ordini successivi, poi un ordine per riga: la bevanda (espresso o tea) e i suoi extra, applicati da sinistra a destra. Per espresso milk large e tea mocha milk l’output è:
Large Espresso + Milk: $8
Tea + Mocha + Milk: $5Il tuo codice va in milk.gd, mocha.gd e large.gd. main.gd contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
extends Node
func _ready():
# Codice di input/output fornito: lascialo così com'è
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()])
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
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggetti a confrontoLa parola chiave selfMetodiProprietàCostruttore (_init)Riepilogo - Calcolatrice semplice4Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme7Segnali
Che cos'è un segnale?Dichiarare ed emettereCollegarsi ai segnaliSegnali con argomentiRipasso - Sistema della salute10Pattern di progettazione, parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern Composite2Proprietà delle classi
Variabili di istanza e staticheFunzioni staticheSetter delle proprietàGetter delle proprietàPrivato per convenzioneRiepilogo - Gestore di conti bancari5Incapsulamento
Membri pubblici e privatiValidazione con i setterNascondimento delle informazioniProprietà di sola letturaRiepilogo - Sistema di gestione dei dati degli studenti8Concetti avanzati di OOP
Composizione vs ereditarietàClassi interneNodi come componentiRefCounted vs NodeEnum nelle classi11Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiCatene di ereditarietàControlli di tipo con isRipasso - Gerarchia dei dipendenti6Metodi speciali
Introduzione ai metodi virtualiIl metodo _to_stringIteratori personalizzatiRiepilogo - Lista personalizzata9Modelli di progettazione, parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore GDScript online