Wzorzec Singleton
Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 46 z 65.
Wzorzec Singleton gwarantuje, że klasa ma dokładnie jeden obiekt i zapewnia każdemu skryptowi jeden sposób dostępu do niego. Używaj go w przypadku elementów, które w grze występują tylko w jednym egzemplarzu: ustawień, systemu zapisu, menedżera wyników.
W GDScript static var przechowuje pojedynczy obiekt, a static func tworzy go za pierwszym razem, gdy ktoś o niego poprosi:
# game_settings.gd
class_name GameSettings
extends RefCounted
static var _instance: GameSettings = null
var volume := 50
static func get_instance() -> GameSettings:
if _instance == null:
_instance = GameSettings.new()
print("Creating settings")
return _instance_instance należy do klasy, a nie do obiektu, więc każdy skrypt widzi tę samą zmienną. Pierwsze wywołanie stwierdza, że jest pusta, i tworzy obiekt; każde kolejne wywołanie zwraca ten sam obiekt.
# main.gd
var a := GameSettings.get_instance()
var b := GameSettings.get_instance()
a.volume = 80
print(b.volume)
print(a == b)Creating settings
80
truea i b to dwie zmienne przechowujące jeden obiekt, więc zmiana dokonana za pośrednictwem a jest widoczna przez b. W przypadku obiektów == ma wartość true tylko wtedy, gdy obie strony są tym samym obiektem.
GDScript nie może uczynić funkcji _init() prywatną, więc nic nie powstrzymuje skryptu przed wywołaniem GameSettings.new() i uzyskaniem drugiego obiektu. Podkreślenie w _instance i metoda get_instance() to umowa: skrypty proszą o obiekt, nigdy go nie tworzą.
W projekcie Godot zwykle uzyskuje się jeden współdzielony obiekt za pomocą autoload: skryptu zarejestrowanego w ustawieniach projektu, który Godot tworzy raz po uruchomieniu gry i udostępnia pod nazwą w każdym skrypcie. To Singleton, którym Godot zarządza za Ciebie. Autoloady konfiguruje się w edytorze, więc w tych wyzwaniach wzorzec jest tworzony w kodzie za pomocą static var.
Wyzwanie
ŁatwyKażda moneta w grze zwiększa jeden wspólny wynik. Zrób z ScoreManager singleton:
static varprzechowuje jedyny obiekt.static func get_instance()zwraca go, tworząc go przy pierwszym wywołaniu. Zaraz po jego utworzeniu wypisujeScore manager created.add_points(points)dodaje punkty doscore.
W pliku coin.gd funkcja collect() dodaje value monety do wyniku za pośrednictwem ScoreManager.get_instance().
Dostarczony kod odczytuje liczbę kolejnych zdarzeń, a następnie po jednym zdarzeniu w każdym wierszu: coin VALUE zbiera nową monetę, a bonus POINTS dodaje punkty bezpośrednio. Po każdym zdarzeniu wypisuje wynik, a na końcu informację, czy dwa wywołania get_instance() zwracają ten sam obiekt. Dla coin 5 i bonus 20 wynik to:
Score manager created
Score: 5
Score: 25
Same object: trueTwój kod umieść w plikach score_manager.gd i coin.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 parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "coin":
Coin.new(int(parts[1])).collect()
elif parts[0] == "bonus":
ScoreManager.get_instance().add_points(int(parts[1]))
print("Score: %d" % ScoreManager.get_instance().score)
print("Same object: %s" % (ScoreManager.get_instance() == ScoreManager.get_instance()))
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