תבנית עיצוב Singleton

הסבר עם דוגמאות ב-PHP לתבנית העיצוב Singleton ולמה היא כל כך חשובה.

לא מזמן התווכחתי עם עמיתים לעבודה בנוגע לתבנית עיצוב Singleton. מדובר בתבנית עיצוב ש-GOF ציינו בספר שלהם. אני טענתי, ברוב בורותי, שמדובר בתבנית עיצוב שהייתי מעדיף שירו בי בראש לפני שאשתמש בה. אך ראש הצוות שלי וחבר הצוות הנוסף טענו שאני דביל. בסוף, בתום ויכוח קצר, הסתבר לי ש(כמובן) טעיתי והם צדקו ומאמר קצר על Singleton יעזור לי לכפר על החטא הנורא של זלזול בתבנית העיצוב הנפלאה הזו.

אז מה זה Singleton? זו תבנית עיצוב שמגבילה את מספר ה-instances שאפשר לעשות ל-class שלה. לכמה? לאחד. מה ההגיון בהגבלה הזו? הרי כל הרעיון מאחורי אובייקטים הוא שנוכל לעשות להם instances כרצוננו! למרות זאת יש מקרים שאם נעשה יותר מ-instance אחד נשחוק את משאבי המערכת ולפעמים גם לא צריך לעשות יותר מ-instance אחד. הדוגמה הקלאסית היא התחברות למסד נתונים – צריך רק חיבור אחד בכל פעם, כי כמה חיבורים פשוט ישביתו את האפליקציה. גם לא צריך יותר מחיבור אחד בכל זמן ריצה, לפיכך כדאי לנו להגביל את כמות ה-instances לאחד.

אולי זה יהיה ברור יותר עם דוגמה.


class Database 
{ 
    public function __construct() { ... } 
    public function connect() { ... } 
    public function query() { ... } 
    ... 
}  

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


class Database 
{ 
    // Store the single instance of Database 
    private static $m_pInstance; 

    ...     
}  

שימו לב שהיא חייבת להיות סטטית.

עכשיו, וזה הקטע המוזר, אנחנו הופכים את הקונסטרקטור למתודה פרטית. רגע, מה? למה פרטית? זה אחד הדברים בתבנית Singleton שקשים לתפיסה. הסיבה שהקונסטרקטור הופך לפרטי היא שאי אפשר יהיה להפעיל אותו 'מבחוץ' וכך אי אפשר יהיה לעשות instance מבחוץ:


class Database 
{ 
    // Store the single instance of Database 
    private static $m_pInstance; 

    private function __construct() { ... } 
}  

על מנת שבכל זאת נוכל להפעיל את ה-class הזה, אנחנו צריכים ליצור מתודה פומבית שהיא זו שתקרא לקונסטרקטור:


public static function getInstance() 
{ 
    if (!self::$m_pInstance) 
    { 
        self::$m_pInstance = new Database(); 
    } 

    return self::$m_pInstance; 
}  

מה המתודה הזו עושה? היא בודקת שהמשתנה הסטטי שיצרנו קודם מלא או ריק. במידה והוא ריק, היא יוצרת instance ל-class באמצעות הקונסטרקטור ומכניסה רפרנס למשתנה הסטטי שיצרנו קודם. במידה והוא מלא, היא פשוט מחזירה את הרפרנס. זה הכל.

לפיכך, אם אנו משתמשים בתבנית עיצוב Singleton, אנחנו נעשה instance לקלאס שלנו באופן הבא:


$pDatabase = Database::getInstance(); 
$aResult = $pDatabase->query('...');  

בניגוד לקלאס רגיל שעושים לו instance ככה:


$pDatabase = new Database(); 
$aResult = $pDatabase->query('...');  

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

אז בסופו של דבר, הטינה שלי כלפי Singleton לא היתה מוצדקת.

פוסטים נוספים שכדאי לקרוא

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

הסבר על טכניקה פשוטה וידועה מאד שאנו מפעילים על מידע לפני שאנחנו מציגים אותו ב-HTML באפליקציה או באתר.

פתרונות ומאמרים על פיתוח אינטרנט

נגישות טכנית – פודקאסט ומבוא

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

בינה מלאכותית

Safeguards על מודל שפה גדול (LLM)

פוסט בשילוב עם פודקאסט וסרטון על ההגנות שאפשר להציב על LLM בסביבת פרודקשן

תמונת תצוגה של מנעול על מחשב
פתרונות ומאמרים על פיתוח אינטרנט

הגנה מפני XSS עם Trusted Types

תכונה ב-CSP שמאפשרת מניעה כמעט הרמטית להתקפות XSS שכל מפתח ווב צריך להכיר וכדאי שיכיר.

תמונה של עציץ, רספברי פיי ורמקול
רספברי פיי

לגרום לעציץ שלכם לדבר

כך תשתמשו ברספברי פיי, חיישנים וגם בינה מלאכותית שמותקנת על הרספברי פיי (כן) כדי ליצור… עציץ המדבר.

גלילה לראש העמוד