Menu
Coddy logo textTech

תבנית Singleton

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 90 מתוך 110.

תבנית Singleton מבטיחה שלמחלקה תהיה מופע אחד בלבד לאורך כל היישום שלך, ומספקת נקודת גישה גלובלית אליו. זה שימושי כשנדרש בדיוק אובייקט אחד כדי לתאם פעולות ברחבי המערכת — כמו מנהל תצורה, חיבור למסד נתונים או שירות רישום.

ב-Dart, אפשר לממש Singleton באמצעות בנאי factory בשילוב עם מופע סטטי פרטי:

class AppConfig {
  static final AppConfig _instance = AppConfig._internal();
  
  String appName = 'MyApp';
  String version = '1.0.0';
  
  // בנאי פרטי בעל שם
  AppConfig._internal();
  
  // בנאי מפעל מחזיר את אותו מופע
  factory AppConfig() {
    return _instance;
  }
}

void main() {
  var config1 = AppConfig();
  var config2 = AppConfig();
  
  config1.appName = 'UpdatedApp';
  
  print(config2.appName);  // UpdatedApp
  print(identical(config1, config2));  // true
}

הבנאי הפרטי _internal() מונע יצירה של מופעים חיצונית. השדה הסטטי _instance מכיל את המופע היחיד, שנוצר פעם אחת כאשר המחלקה נטענת. כל קריאה ל־AppConfig() מחזירה את אותו המופע, כך ששינויים שנעשים דרך הפניה אחת גלויים בכל מקום.

השתמשו ב-Singletons במשורה — הם יוצרים מצב גלובלי, שעלול להקשות על הבדיקות. הם מתאימים במיוחד למשאבים משותפים באמת שזקוקים למצב עקבי בכל רחבי האפליקציה שלכם.

challenge icon

אתגר

קל

בוא נבנה מנהל הגדרות למשחק באמצעות תבנית Singleton! תיצור מערכת שמבטיחה שקיים רק מופע אחד של הגדרות המשחק בכל היישום, כך שכל חלקי המשחק שלך ישתפו את אותה התצורה.

תארגן את הקוד שלך בשני קבצים:

  • game_settings.dart: צור מחלקת GameSettings שמיישמת את תבנית Singleton. למנהל ההגדרות שלך יהיו:
    • מופע פרטי, סטטי וסופי, שמכיל את אובייקט GameSettings היחיד
    • בנאי פרטי בעל שם, כדי למנוע יצירה חיצונית של מופעים
    • בנאי factory שתמיד מחזיר את אותו המופע
    • שלושה שדות הגדרות: difficulty (String, ברירת מחדל: "Normal"), soundEnabled (bool, ברירת מחדל: true), ו-playerName (String, ברירת מחדל: "Player1")
    • מתודה displaySettings() שמדפיסה את ההגדרות הנוכחיות בפורמט הזה: Settings: [playerName] | Difficulty: [difficulty] | Sound: [on/off] (הדפס "on" אם soundEnabled הוא true, ו-"off" אם הוא false)
  • main.dart: ייבא את הגדרות המשחק שלך והדגם שתבנית Singleton פועלת כהלכה:
    • קבל את מופע ההגדרות וקרא לו settings1
    • קרא ל-displaySettings() כדי להציג את ערכי ברירת המחדל
    • שנה את ההגדרות: שנה את playerName ל-"Hero", את difficulty ל-"Hard", ואת soundEnabled ל-false
    • קבל הפניה נוספת להגדרות וקרא לה settings2
    • קרא ל-displaySettings() על settings2 כדי להוכיח שהיא משקפת את השינויים שבוצעו דרך settings1
    • הדפס אם settings1 ו-settings2 זהים, באמצעות: Same instance: [true/false]

כך מודגם היתרון המרכזי של מופעי Singleton — שינויים שנעשים בכל מקום ביישום שלך גלויים מיד בכל מקום אחר, כי יש רק מופע אחד!

פלט צפוי:

Settings: Player1 | Difficulty: Normal | Sound: on
Settings: Hero | Difficulty: Hard | Sound: off
Same instance: true

נסו בעצמכם

import 'game_settings.dart';

void main() {
  // TODO: קבלו את מופע ההגדרות וקראו לו settings1
  
  // TODO: קראו ל-displaySettings() כדי להציג את ערכי ברירת המחדל
  
  // TODO: שנו את ההגדרות:
  // - שנו את playerName ל-"Hero"
  // - שנו את difficulty ל-"Hard"
  // - שנו את soundEnabled ל-false
  
  // TODO: קבלו הפניה נוספת להגדרות וקראו לה settings2
  
  // TODO: קראו ל-displaySettings() על settings2 כדי להוכיח שהוא משקף את השינויים
  
  // TODO: הדפיסו אם settings1 ו-settings2 זהים
  // פורמט: Same instance: [true/false]
}
quiz iconבחנו את עצמכם

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

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

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