어댑터 패턴
Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 51번째.
Adapter 패턴을 사용하면 객체가 다른 메서드를 예상하는 코드와 함께 작동할 수 있습니다. 어댑터는 객체를 감싸고, 예상되는 각 호출을 객체가 이해하는 호출로 바꿉니다.
이전 프로젝트의 오래된 클래스는 체력을 두 개의 숫자로 저장합니다:
# old_monster.gd
class_name OldMonster
extends RefCounted
var life := 30
var max_life := 120HUD에는 get_label()과 get_hp_percent()가 있는 모든 항목이 표시됩니다. Knight에는 이미 두 메서드가 모두 있지만(각각 "Knight"와 80을 반환합니다), OldMonster에는 둘 다 없습니다:
# health_display.gd
class_name HealthDisplay
extends RefCounted
func show_health(target) -> void:
print(target.get_label(), ": ", target.get_hp_percent(), "%")어댑터는 OldMonster를 보유하고 디스플레이가 호출하는 두 메서드를 제공합니다:
# monster_adapter.gd
class_name MonsterAdapter
extends RefCounted
var monster: OldMonster
func _init(wrapped: OldMonster) -> void:
monster = wrapped
func get_label() -> String:
return "Monster"
func get_hp_percent() -> int:
return monster.life * 100 / monster.max_life# main.gd
var display := HealthDisplay.new()
display.show_health(Knight.new())
display.show_health(MonsterAdapter.new(OldMonster.new()))Knight: 80%
Monster: 25%OldMonster도 HealthDisplay도 변경되지 않았습니다. 클래스를 수정할 수 없거나 수정해서는 안 될 때 이는 중요합니다. 클래스가 플러그인에서 제공되거나, 다른 팀이 소유하고 있거나, 많은 스크립트가 그 이름에 의존하기 때문입니다.
어댑터는 호출을 각각 전달하고 데이터를 전달하는 과정에서 변환합니다. 여기서는 두 숫자를 하나의 백분율로 변환합니다. 나누기 전에 곱하세요. 정수의 경우 30 / 120 * 100은 0이고, 30 * 100 / 120은 25입니다.
챌린지
쉬움날씨 보드에는 get_sensor_name()과 get_celsius()가 있는 센서가 표시됩니다. 예를 들어 ModernSensor(modern_sensor.gd)가 있습니다. 보드는 weather_board.gd에 있습니다. 오래된 온도계(legacy_thermometer.gd)는 read_fahrenheit()와 get_code()만 제공합니다. 어댑터 ThermometerAdapter를 작성하세요.
- 생성자는 래핑된
LegacyThermometer를 저장합니다. get_sensor_name()은Thermometer, 공백, 그리고 온도계의 코드를 반환합니다. 예:Thermometer TH-4.get_celsius()는 섭씨 온도를(fahrenheit - 32) * 5 / 9로 계산하여float로 반환합니다.
다른 클래스는 변경하지 마세요. 제공된 코드는 이어지는 센서의 개수를 읽은 다음, 한 줄에 하나씩 legacy ID FAHRENHEIT 또는 modern NAME CELSIUS 형식으로 입력을 읽습니다. 모든 오래된 온도계를 여러분의 어댑터로 감싸고 모든 센서를 표시합니다. legacy 4 98.6과 modern Garden 21.5를 입력하면 출력은 다음과 같습니다.
Thermometer TH-4: 37.0 C
Garden: 21.5 C
Warmest: Thermometer TH-4코드는 thermometer_adapter.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.
직접 해보기
extends Node
func _ready():
# 제공된 입력/출력 코드: 수정하지 말고 그대로 두세요
var board := WeatherBoard.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "legacy":
var old := LegacyThermometer.new(int(parts[1]), float(parts[2]))
board.add_sensor(ThermometerAdapter.new(old))
else:
board.add_sensor(ModernSensor.new(parts[1], float(parts[2])))
board.show_all()
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러