팩토리 패턴
Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 47번째.
팩터리 패턴은 어떤 클래스를 생성할지 선택하는 작업을 한곳으로 모읍니다. 프로그램의 나머지 부분은 팩터리에 "고블린"을 요청하고 객체를 돌려받으며, 클래스 이름인 Goblin은 명시하지 않습니다.
제품들이 부모 클래스를 공유하므로, 제품을 사용하는 코드는 어떤 제품과도 함께 작동합니다:
# enemy.gd
class_name Enemy
extends RefCounted
var hp := 10
func attack() -> String:
return "The enemy waits"# goblin.gd
class_name Goblin
extends Enemy
func attack() -> String:
return "The goblin stabs"# orc.gd
class_name Orc
extends Enemy
func attack() -> String:
return "The orc smashes"팩토리는 이름을 객체로 바꾸는 static func이 있는 클래스입니다. 반환 유형은 부모 클래스이므로 모든 종류의 적을 반환할 수 있으며, 알지 못하는 이름에는 null을 반환할 수 있습니다:
# enemy_factory.gd
class_name EnemyFactory
extends RefCounted
static func create(kind: String) -> Enemy:
match kind:
"goblin":
return Goblin.new()
"orc":
return Orc.new()
return null# main.gd
for kind in ["orc", "goblin", "slime"]:
var enemy := EnemyFactory.create(kind)
if enemy == null:
print("Unknown enemy: ", kind)
else:
print(enemy.attack())The orc smashes
The goblin stabs
Unknown enemy: slime이런 이름은 보통 스폰 테이블, 레벨 파일, 플레이어가 입력한 명령어 같은 데이터에서 가져옵니다. 팩토리는 이 이름을 클래스에 매핑하는 유일한 곳이므로, Dragon을 추가하려면 새 파일 하나와 match에 새 분기 하나만 추가하면 됩니다.
팩토리는 객체를 반환하기 전에 설정할 수도 있으므로, 모든 호출자가 바로 사용할 수 있는 적을 받습니다:
static func create_boss(kind: String, level: int) -> Enemy:
var boss := create(kind)
if boss != null:
boss.hp = 100 * level
return bossEnemyFactory.create_boss("orc", 3)는 HP가 300인 Orc를 반환합니다.
챌린지
중급생성 테이블에는 적과 레벨이 지정되어 있습니다. Enemy(enemy.gd)와 그 하위 클래스인 Goblin(goblin.gd)은 작성되어 있습니다. 나머지를 완성하세요:
orc.gd에서 생성자_init(level)는Goblin이 하는 것처럼 이름Orc, HP25 * level, 피해량4 + level을 부모 생성자에 전달합니다.enemy_factory.gd에서static func create(kind, level)은goblin이면Goblin을,orc이면 해당 레벨로 생성한Orc를 반환합니다. 이름의 대소문자는 중요하지 않습니다(ORC도 오크입니다). 그 밖의 이름은null을 반환합니다.
제공된 코드는 이어지는 생성 횟수를 읽고, 생성마다 KIND LEVEL 형식의 한 줄을 읽은 다음, 각 적 또는 Unknown enemy: KIND를 출력하고 마지막으로 생성된 적의 수를 출력합니다. goblin 2, Orc 3, slime 1을 입력하면 출력은 다음과 같습니다:
Goblin: 20 HP, 4 damage
Orc: 75 HP, 7 damage
Unknown enemy: slime
Spawned: 2코드는 enemy_factory.gd와 orc.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.
직접 해보기
extends Node
func _ready():
# 제공된 입력/출력 코드: 그대로 유지하세요
var spawned := 0
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
var enemy := EnemyFactory.create(parts[0], int(parts[1]))
if enemy == null:
print("Unknown enemy: ", parts[0])
else:
spawned += 1
print(enemy.describe())
print("Spawned: ", spawned)
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러