Menu
CoddyTech

Ocultación de información

Parte de la sección Programación orientada a objetos del Journey de GDScript de Coddy. Lección 28 de 65.

La ocultación de información va un paso más allá que las variables privadas: el código que usa una clase depende únicamente de lo que hacen sus métodos públicos, nunca de cómo almacena la clase sus datos. Después, puedes cambiar el almacenamiento sin tocar ese código.

# 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 true

main.gd llama a add(), count() y remove() y nunca ve el Dictionary. Si más adelante Inventory guarda un Array de espacios en su lugar, solo cambia inventory.gd.

Ten cuidado con los getters que devuelven un Array o un Dictionary. GDScript entrega estos valores por referencia: quien llama obtiene el Array propio del objeto, no una copia, y puede modificarlo sin pasar por los métodos de la clase:

# 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"]

Devuelve una copia en su lugar. duplicate() crea un nuevo Array con los mismos elementos, así que los cambios que hagas en él quedan fuera del objeto:

func get_quests() -> Array[String]:
	return _quests.duplicate()

Para un Dictionary o un Array que contiene otros Array, usa duplicate(true): también copia los Array y Dictionary internos.

challenge icon

Desafío

Fácil

Escribe la clase Playlist en playlist.gd. Mantiene los títulos de las canciones en el Array privado _songs, y el resto del código usa solo estos métodos:

  • add(title) agrega el título y devuelve true. Si el título ya está en la lista de reproducción, no cambia nada y devuelve false.
  • remove(title) elimina el título y devuelve true, o devuelve false si no está.
  • count() devuelve el número de canciones.
  • get_titles() devuelve una copia de los títulos, en el orden en que se agregaron.

El código proporcionado lee el número de comandos, luego un comando por línea (add Blue Sky o remove Blue Sky) e imprime el resultado. Al final, toma el Array de get_titles(), agrega Intruder y lo invierte, luego imprime el número de canciones y los títulos. Tu lista de reproducción no debe verse afectada por esos cambios. Para los comandos add Blue Sky, add Rain y add Blue Sky, imprime:

Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, Rain

Tu código va en playlist.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 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)
	# Código que intenta modificar la lista que recibe
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
quiz iconPonte a prueba

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

Practica por tu cuenta: Compilador de GDScript online