Patrón Adapter
Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 51 de 65.
El patrón Adapter permite que un objeto funcione con código que espera métodos diferentes. El adaptador envuelve el objeto y convierte cada llamada esperada en una llamada que el objeto entiende.
Una clase antigua de un proyecto anterior almacena la salud como dos números:
# old_monster.gd
class_name OldMonster
extends RefCounted
var life := 30
var max_life := 120Tu HUD muestra cualquier cosa que tenga get_label() y get_hp_percent(). Un Knight ya tiene ambos (devuelve "Knight" y 80), pero OldMonster no tiene ninguno:
# health_display.gd
class_name HealthDisplay
extends RefCounted
func show_health(target) -> void:
print(target.get_label(), ": ", target.get_hp_percent(), "%")El adaptador contiene un OldMonster y proporciona los dos métodos que llama la pantalla:
# 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%Ni OldMonster ni HealthDisplay cambiaron. Eso importa cuando no puedes o no debes editar una clase: proviene de un complemento, pertenece a otro equipo o muchos scripts dependen de sus nombres.
El adaptador reenvía cada llamada y convierte los datos sobre la marcha: aquí, dos números en un porcentaje. Multiplica antes de dividir: con enteros, 30 / 120 * 100 es 0, mientras que 30 * 100 / 120 es 25.
Desafío
FácilUna estación meteorológica muestra sensores que tienen get_sensor_name() y get_celsius(), como ModernSensor (modern_sensor.gd). La estación está en weather_board.gd. Los termómetros antiguos (legacy_thermometer.gd) solo ofrecen read_fahrenheit() y get_code(). Escribe el adaptador ThermometerAdapter:
- El constructor guarda el
LegacyThermometerenvuelto. get_sensor_name()devuelveThermometer, un espacio y el código del termómetro, comoThermometer TH-4.get_celsius()devuelve la temperatura en Celsius:(fahrenheit - 32) * 5 / 9, comofloat.
No cambies las demás clases. El código proporcionado lee cuántos sensores vienen a continuación y luego uno por línea: legacy ID FAHRENHEIT o modern NAME CELSIUS. Envuelve cada termómetro antiguo en tu adaptador y muestra todos los sensores. Para legacy 4 98.6 y modern Garden 21.5, la salida es:
Thermometer TH-4: 37.0 C
Garden: 21.5 C
Warmest: Thermometer TH-4Tu código va en thermometer_adapter.gd. main.gd contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
extends Node
func _ready():
# Código de entrada/salida proporcionado: mantenlo tal como está
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()
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Fundamentos de la programación orientada a objetos
Archivos externosIntroducción a la programación orientada a objetosClases vs. objetosLa palabra clave selfMétodosPropiedadesConstructor (_init)Repaso: calculadora sencilla4Polimorfismo
Repaso de la sobrescritura de métodosTipado patoClases y métodos abstractosDiseño de interfacesRepaso: calculadora de formas7Señales
¿Qué es una señal?Declarar y emitirConectarse a las señalesSeñales con argumentosRepaso: sistema de salud10Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite2Propiedades de clase
Variables de instancia y estáticasFunciones estáticasMétodos setter de propiedadesMétodos getter de propiedadesPrivado por convenciónRepaso: administrador de cuentas bancarias5Encapsulación
Miembros públicos y privadosValidación con settersOcultación de informaciónPropiedades de solo lecturaRepaso: sistema de registros de estudiantes8Conceptos avanzados de POO
Composición frente a herenciaClases internasNodos como componentesRefCounted frente a NodeEnums en clases3Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosCadenas de herenciaComprobaciones de tipo con isRepaso: jerarquía de empleados6Métodos especiales
Introducción a los métodos virtualesEl método _to_stringIteradores personalizadosRepaso: lista personalizada9Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de GDScript online