Menu
CoddyTech

Pola State

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GDScript di Coddy. Pelajaran 54 dari 65.

Pola State memberi sebuah object state terpisah untuk setiap mode yang dapat dimilikinya. Object tersebut menyerahkan pekerjaannya kepada state saat ini, sehingga perilakunya berubah saat state berubah.

Untuk beberapa state, enum dan match sudah cukup. Saat setiap state bereaksi terhadap beberapa aksi dengan caranya sendiri, match itu bertambah panjang dengan setiap state dan setiap aksi. Pola State memindahkan aturan setiap state ke class-nya sendiri:

# hero_state.gd
@abstract
class_name HeroState
extends RefCounted

@abstract func get_state_name() -> String
@abstract func handle(action: String) -> HeroState

handle() mengembalikan state berikutnya: object state baru untuk beralih ke sana, atau self untuk tetap di sini.

# idle_state.gd
class_name IdleState
extends HeroState

func get_state_name() -> String:
	return "Idle"

func handle(action: String) -> HeroState:
	if action == "run":
		return RunState.new()
	return self

RunState ditulis dengan cara yang sama: namanya adalah "Running", dan "stop" mengembalikan IdleState.new(). Hero, yaitu konteksnya, menyimpan state saat ini dan menanyakan apa yang harus dilakukan:

# hero.gd
class_name Hero
extends RefCounted

var state: HeroState = IdleState.new()

func handle_action(action: String) -> void:
	var next := state.handle(action)
	if next != state:
		print(state.get_state_name(), " -> ", next.get_state_name())
		state = next
# main.gd
var hero := Hero.new()
for action in ["stop", "run", "run", "stop"]:
	hero.handle_action(action)
Idle -> Running
Running -> Idle

Aksi yang sama memiliki arti berbeda dalam state yang berbeda: "stop" tidak melakukan apa pun saat idle dan menghentikan hero yang sedang berlari. Setiap aturan berada di class untuk state-nya, jadi state baru, seperti melompat, berarti satu class baru.

Status-status mengembalikan status berikutnya alih-alih menyimpan hero. Status yang menyimpan hero sementara hero menyimpan status akan membentuk siklus referensi, dan kedua object tidak akan pernah dibebaskan.

challenge icon

Tantangan

Mudah

Pintu berada dalam keadaan Locked, Closed, atau Open. DoorState (door_state.gd) mendeklarasikan get_state_name() dan handle(action), sedangkan LockedState (locked_state.gd) sudah ditulis: unlock membuat pintu menjadi Closed. Tulis:

  • ClosedState.handle(): open mengembalikan OpenState baru, lock mengembalikan LockedState baru, dan tindakan lainnya mengembalikan self.
  • OpenState.handle(): close mengembalikan ClosedState baru, dan tindakan lainnya mengembalikan self.
  • Door.handle_action(action): meminta state saat ini untuk menentukan state berikutnya. Jika objeknya sama, cetak ACTION: still STATE; jika tidak, cetak ACTION: OLD -> NEW dan beralih ke state baru.

Pintu dimulai dalam keadaan Locked. Kode yang disediakan membaca jumlah tindakan yang akan diberikan, lalu membaca satu tindakan per baris, dan mencetak state akhir. Untuk open, unlock, open, lock, output-nya adalah:

open: still Locked
unlock: Locked -> Closed
open: Closed -> Open
lock: still Open
Final state: Open

Tulis kodemu di door.gd, closed_state.gd, dan open_state.gd. main.gd berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

extends Node

func _ready():
	# Kode input/output yang disediakan: biarkan tetap seperti ini
	var door := Door.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		door.handle_action(OS.read_string_from_stdin())
	print("Final state: ", door.state.get_state_name())
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler GDScript online