Menu
CoddyTech

Pattern Adapter

Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 51 di 65.

Il pattern Adapter permette a un oggetto di funzionare con codice che si aspetta metodi diversi. L'adattatore avvolge l'oggetto e trasforma ogni chiamata prevista in una chiamata che l'oggetto comprende.

Una vecchia classe di un progetto precedente memorizza la salute come due numeri:

# old_monster.gd
class_name OldMonster
extends RefCounted

var life := 30
var max_life := 120

Il tuo HUD mostra tutto ciò che ha get_label() e get_hp_percent(). Un Knight li ha già entrambi (restituisce "Knight" e 80), ma OldMonster non ha né l’uno né l’altro:

# health_display.gd
class_name HealthDisplay
extends RefCounted

func show_health(target) -> void:
	print(target.get_label(), ": ", target.get_hp_percent(), "%")

L'adattatore contiene un OldMonster e fornisce i due metodi che il display chiama:

# monster_adapter.gd
class_name MonsterAdapter
extends RefCounted

var monster: OldMonster

func _init(wrapped: OldMonster) -> void:
	monster = wrapped

func get_label() -> String:
	return "Monster"

func get_hp_percent() -> int:
	return monster.life * 100 / monster.max_life
# main.gd
var display := HealthDisplay.new()
display.show_health(Knight.new())
display.show_health(MonsterAdapter.new(OldMonster.new()))
Knight: 80%
Monster: 25%

Né OldMonster né HealthDisplay sono stati modificati. Questo è importante quando non puoi o non dovresti modificare una classe: proviene da un plugin, è gestita da un altro team oppure molti script dipendono dai suoi nomi.

L’adattatore inoltra ogni chiamata e converte i dati durante il passaggio: qui trasforma due numeri in una percentuale. Moltiplica prima di dividere: con gli interi, 30 / 120 * 100 dà 0, mentre 30 * 100 / 120 dà 25.

challenge icon

Sfida

Facile

Una scheda meteo mostra i sensori che hanno get_sensor_name() e get_celsius(), come ModernSensor (modern_sensor.gd). La scheda si trova in weather_board.gd. I vecchi termometri (legacy_thermometer.gd) offrono solo read_fahrenheit() e get_code(). Scrivi l’adattatore ThermometerAdapter:

  • Il costruttore memorizza il LegacyThermometer avvolto.
  • get_sensor_name() restituisce Thermometer, uno spazio e il codice del termometro, come Thermometer TH-4.
  • get_celsius() restituisce la temperatura in Celsius: (fahrenheit - 32) * 5 / 9, come float.

Non modificare le altre classi. Il codice fornito legge quanti sensori seguono, poi uno per riga: legacy ID FAHRENHEIT oppure modern NAME CELSIUS. Avvolge ogni vecchio termometro nel tuo adattatore e mostra tutti i sensori. Per legacy 4 98.6 e modern Garden 21.5, l’output è:

Thermometer TH-4: 37.0 C
Garden: 21.5 C
Warmest: Thermometer TH-4

Il tuo codice va in thermometer_adapter.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 board := WeatherBoard.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "legacy":
			var old := LegacyThermometer.new(int(parts[1]), float(parts[2]))
			board.add_sensor(ThermometerAdapter.new(old))
		else:
			board.add_sensor(ModernSensor.new(parts[1], float(parts[2])))
	board.show_all()
quiz iconMettiti alla prova

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

Esercitati da solo: Compilatore GDScript online