Patron Adaptateur
Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 51 sur 65.
Le modèle Adaptateur permet à un objet de fonctionner avec du code qui attend des méthodes différentes. L’adaptateur enveloppe l’objet et transforme chaque appel attendu en un appel que l’objet comprend.
Une ancienne classe d’un projet précédent stocke la santé sous forme de deux nombres :
# old_monster.gd
class_name OldMonster
extends RefCounted
var life := 30
var max_life := 120Votre HUD affiche tout ce qui possède get_label() et get_hp_percent(). Un Knight possède déjà les deux (il renvoie "Knight" et 80), mais OldMonster ne possède ni l’un ni l’autre :
# health_display.gd
class_name HealthDisplay
extends RefCounted
func show_health(target) -> void:
print(target.get_label(), ": ", target.get_hp_percent(), "%")L’adaptateur contient un OldMonster et fournit les deux méthodes appelées par l’affichage :
# 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 n’ont changé. C’est important lorsque vous ne pouvez pas ou ne devez pas modifier une classe : elle provient d’un plug-in, appartient à une autre équipe ou de nombreux scripts dépendent de ses noms.
L’adaptateur transmet chaque appel et convertit les données au passage, ici deux nombres en un pourcentage. Multipliez avant de diviser : avec des entiers, 30 / 120 * 100 vaut 0, tandis que 30 * 100 / 120 vaut 25.
Défi
FacileUn tableau météo affiche des capteurs qui possèdent get_sensor_name() et get_celsius(), comme ModernSensor (modern_sensor.gd). Le tableau se trouve dans weather_board.gd. Les anciens thermomètres (legacy_thermometer.gd) proposent uniquement read_fahrenheit() et get_code(). Écris l’adaptateur ThermometerAdapter :
- Le constructeur stocke le
LegacyThermometerenveloppé. get_sensor_name()renvoieThermometer, une espace et le code du thermomètre, commeThermometer TH-4.get_celsius()renvoie la température en Celsius :(fahrenheit - 32) * 5 / 9, sous forme defloat.
Ne modifie pas les autres classes. Le code fourni lit le nombre de capteurs qui suivent, puis un capteur par ligne : legacy ID FAHRENHEIT ou modern NAME CELSIUS. Il enveloppe chaque ancien thermomètre dans ton adaptateur et affiche tous les capteurs. Pour legacy 4 98.6 et modern Garden 21.5, la sortie est :
Thermometer TH-4: 37.0 C
Garden: 21.5 C
Warmest: Thermometer TH-4Ton code va dans thermometer_adapter.gd. main.gd contient le code d’entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
extends Node
func _ready():
# Code d’entrée/sortie fourni : conservez-le tel quel
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()
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé selfMéthodesPropriétésConstructeur (_init)Récapitulatif - Calculatrice simple4Polymorphisme
Retour sur la redéfinition des méthodesTypage canardClasses et méthodes abstraitesConception d’interfacesRécapitulatif – Calculateur de formes7Signaux
Qu’est-ce qu’un signal ?Déclarer et émettreSe connecter aux signauxSignaux avec argumentsRécapitulatif - système de santé10Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron Composite2Propriétés de classe
Variables d’instance et variables statiquesFonctions statiquesSetters de propriétésGetters de propriétésPrivé par conventionRécapitulatif - Gestionnaire de comptes bancaires5Encapsulation
Membres publics et privésValidation avec les méthodes setterMasquage de l’informationPropriétés en lecture seuleRécapitulatif - Système de dossiers étudiants8Concepts avancés de la POO
Composition ou héritageClasses internesLes nœuds comme composantsRefCounted ou NodeEnums dans les classes3Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodesChaînes d’héritageVérifier les types avec isRécapitulatif – Hiérarchie des employés6Méthodes spéciales
Introduction aux méthodes virtuellesLa méthode _to_stringItérateurs personnalisésRécapitulatif – Liste personnalisée9Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur GDScript en ligne