Menu
CoddyTech

Ocultação de informações

Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 28 de 65.

Ocultação de informações vai um passo além das variáveis privadas: o código que usa uma classe depende apenas do que seus métodos públicos fazem, nunca de como a classe armazena seus dados. Assim, você pode alterar o armazenamento sem tocar nesse 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 chama add(), count() e remove() e nunca vê o Dictionary. Se Inventory passar a manter um Array de espaços em vez disso, somente inventory.gd será alterado.

Tenha cuidado com getters que retornam um Array ou um Dictionary. O GDScript fornece esses valores por referência: quem chama recebe o próprio Array do objeto, não uma cópia, e pode alterá-lo sem passar pelos métodos da 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"]

Retorne uma cópia. duplicate() cria um novo Array com os mesmos elementos, então as alterações nele ficam fora do objeto:

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

Para um Dictionary ou um Array que contém outros Arrays, use duplicate(true): ele também copia os Arrays e os Dictionaries internos.

challenge icon

Desafio

Fácil

Escreva a classe Playlist em playlist.gd. Ela mantém os títulos das músicas no Array privado _songs, e outros códigos usam apenas estes métodos:

  • add(title) acrescenta o título e retorna true. Se o título já estiver na playlist, não altera nada e retorna false.
  • remove(title) remove o título e retorna true, ou retorna false quando ele não está na playlist.
  • count() retorna o número de músicas.
  • get_titles() retorna uma cópia dos títulos, na ordem em que foram adicionados.

O código fornecido lê o número de comandos e, em seguida, um comando por linha (add Blue Sky ou remove Blue Sky) e imprime o resultado. No final, ele obtém o Array de get_titles(), acrescenta Intruder e o inverte, depois imprime a quantidade de músicas e os títulos. Sua playlist não deve ser afetada por essas alterações. Para os comandos add Blue Sky, add Rain e add Blue Sky, imprime:

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

Seu código deve ficar em playlist.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

extends Node

func _ready():
	# Código de entrada/saída fornecido: mantenha-o 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 tenta alterar a lista que recebe de volta
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação orientada a objetos

Pratique por conta própria: Compilador de GDScript online