מדריך למימוש Singleton Pattern

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

Singleton הינה תבנית יצרנית, כמו גם Builder pattern ו – Factory pattern שדיברנו עליהם בפוסטים הקודמים, שמאפשרת לנו לייצר אובייקט בעל ייצוג יחידני, ובעברית: התבנית תייצר פעם אחת בלבד את האובייקט הרצוי, ומפה והלאה בכל מקום בתוכנית שנצטרך לאובייקט זה נוכל לקבל את ה-Instance שייצרנו בפעם הראשונה, כלומר, בכל מקום שהאובייקט יופיע הוא תמיד יצביע לאותו מקום בזיכרון.

למה אני צריך את זה?!

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

אז מה אתה מציע?

במקרה הזה ברור לנו שאנחנו רוצים  Instance יחיד של Log שאך ורק הוא יוכל לכתוב לקובץ ה-Log בכל זמן נתון, וכך בעצם נוכל לדאוג שהקובץ שנקבל בסוף יהיה קריא ובאמת יצביע לנו על התהליך שנעשה.

בואו נראה רגע איך יראה הפיתרון ש-Singleton מציעה לנו בצורה סכמתית:

Singleton – סכמת UML

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

מימוש בעיית ה-Log בקוד שלנו

תחילה נראה כיצד תהיה בנויה המחלקה שמייצרת את ה-Logger (אובייקט ה-Singleton במקרה שלנו):

חשוב לשים לב לכמה נקודות-

  •  בנאי המחלקה מוגדר כ-Private כדי שלא תהיה אפשרות לייצר אובייקטים בצורה לא מבוקרת.
  • האובייקט Logger ייוצר רק בפעם הראשונה הרלוונטית ומפה והלאה נחזיר את אותו האובייקט.
  • המתודה GetInstance חייבת להיות סטטית (static) , אחרת למשתמש לא תהיה גישה אליה בגלל שעוד אין לו אובייקט מסוג Logger.
  • כתוצאה מהסעיף הקודם נצטרך שהמשתנה instance במחלקה Logger יהיה גם הוא סטטי, כדי  לאפשר ל-GetInstance לגשת אליו.

ולסיום נראה את השימוש ב-Logger שלנו:

פלט התכונית יהיה כמובן:

logger1 == logger2 : True

לסיכום

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

עד כאן להיום חברים.

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

ניפגש בפעם הבאה!

One Reply to “מדריך למימוש Singleton Pattern”

  1. פוסט מעולה.
    אני מקווה שתמשיך עם הפרסום של ההסברים על התבניות השונות.

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *