Menu
CoddyTech

תבנית המתאם

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 51 מתוך 65.

תבנית Adapter מאפשרת לאובייקט לעבוד עם קוד שמצפה למתודות שונות. המתאם עוטף את האובייקט והופך כל קריאה מצופה לקריאה שהאובייקט מבין.

מחלקה ישנה מפרויקט קודם מאחסנת את הבריאות כשני מספרים:

# old_monster.gd
class_name OldMonster
extends RefCounted

var life := 30
var max_life := 120

ה-HUD שלך מציג כל דבר שיש לו 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.

challenge icon

אתגר

קל

לוח מזג אוויר מציג חיישנים שיש להם 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()
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר GDScript אונליין