Masquage de l’information
Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 28 sur 65.
Le masquage de l’information va plus loin que les variables privées : le code qui utilise une classe dépend uniquement du comportement de ses méthodes publiques, jamais de la façon dont la classe stocke ses données. Tu peux alors modifier le stockage sans toucher à ce code.
# inventory.gd
class_name Inventory
extends RefCounted
var _counts: Dictionary = {}
func add(item: String, amount: int) -> void:
_counts[item] = _counts.get(item, 0) + amount
func count(item: String) -> int:
return _counts.get(item, 0)
func remove(item: String, amount: int) -> bool:
if count(item) < amount:
return false
_counts[item] -= amount
return truemain.gd appelle add(), count() et remove() et ne voit jamais le Dictionary. Si Inventory conserve ensuite un Array d’emplacements à la place, seul inventory.gd change.
Fais attention aux accesseurs qui renvoient un tableau ou un dictionnaire. GDScript transmet ces valeurs par référence : l’appelant obtient le tableau propre à l’objet, et non une copie, et peut le modifier sans passer par les méthodes de la classe :
# quest_log.gd
var _quests: Array[String] = ["Find the key"]
func get_quests() -> Array[String]:
return _quests# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]Retourne plutôt une copie. duplicate() crée un nouveau tableau contenant les mêmes éléments, ainsi les modifications qui lui sont apportées restent en dehors de l’objet :
func get_quests() -> Array[String]:
return _quests.duplicate()Pour un dictionnaire ou un tableau contenant d’autres tableaux, utilisez duplicate(true) : cette méthode copie également les tableaux et dictionnaires internes.
Défi
FacileÉcrivez la classe Playlist dans playlist.gd. Elle conserve les titres des chansons dans l’Array privé _songs, et les autres codes utilisent uniquement ces méthodes :
add(title)ajoute le titre et renvoietrue. Si le titre figure déjà dans la playlist, elle ne change rien et renvoiefalse.remove(title)supprime le titre et renvoietrue, ou renvoiefalses’il n’y figure pas.count()renvoie le nombre de chansons.get_titles()renvoie une copie des titres, dans l’ordre où ils ont été ajoutés.
Le code fourni lit le nombre de commandes, puis une commande par ligne (add Blue Sky ou remove Blue Sky) et affiche le résultat. À la fin, il récupère l’Array renvoyé par get_titles(), y ajoute Intruder et inverse son ordre, puis affiche le nombre de chansons et les titres. Votre playlist ne doit pas être affectée par ces modifications. Pour les commandes add Blue Sky, add Rain et add Blue Sky, il affiche :
Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, RainVotre code doit être placé dans playlist.gd. main.gd contient le code fourni pour les entrées/sorties 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 playlist := Playlist.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ", true, 1)
var title := parts[1]
if parts[0] == "add":
if playlist.add(title):
print("Added: " + title)
else:
print("Already in the playlist: " + title)
elif playlist.remove(title):
print("Removed: " + title)
else:
print("Not found: " + title)
# Code qui tente de modifier la liste qu’il récupère
var titles := playlist.get_titles()
titles.append("Intruder")
titles.reverse()
print("Songs: %d" % playlist.count())
print(", ".join(playlist.get_titles()))
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