Singleton בטוח לריבוי תהליכונים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 52 מתוך 70.
תבנית Singleton מבטיחה שלמחלקה תהיה מופע אחד בלבד בכל רחבי היישום שלך ומספקת נקודת גישה גלובלית אליו. התבנית שימושית לניהול משאבים משותפים, כמו הגדרות תצורה, שירותי רישום ביומן או חיבורי מסד נתונים.
Singleton בסיסי משתמש בבנאי פרטי כדי למנוע יצירה של מופעים מבחוץ ובמאפיין סטטי כדי לספק גישה:
public class Logger
{
private static Logger _instance;
private static readonly object _lock = new object();
private Logger() { } // בנאי פרטי
public static Logger Instance
{
get
{
lock (_lock)
{
if (_instance == null)
_instance = new Logger();
return _instance;
}
}
}
public void Log(string message) => Console.WriteLine(message);
}הפקודה lock מבטיחה בטיחות בתהליכונים — אם כמה תהליכונים מנסים לגשת אל Instance בו־זמנית, רק אחד מהם יכול להיכנס למקטע הקריטי בכל פעם. בלי זה, שני תהליכונים עלולים לראות ש־_instance הוא null וליצור מופעים נפרדים.
C# מציעה גישה פשוטה יותר ובטוחה לשימוש בתהליכונים, באמצעות אתחול סטטי:
public class Logger
{
private static readonly Logger _instance = new Logger();
private Logger() { }
public static Logger Instance => _instance;
public void Log(string message) => Console.WriteLine(message);
}גרסה זו בטוחה לשימוש במקביל, כי ה־CLR מבטיח שאתחול של שדות סטטיים מתבצע פעם אחת בלבד. שתי הגישות מבטיחות שתקבלו תמיד את אותו מופע:
Logger.Instance.Log("First call");
Logger.Instance.Log("Same instance");אתגר
קלבואו נבנה מנהל תצורה בטוח לשימוש במקביל באמצעות תבנית Singleton. ביישומים אמיתיים, יש לאפשר גישה להגדרות התצורה מכל חלקי התוכנית, תוך הבטחה שקיים רק מופע אחד — זהו מקרה שימוש מושלם עבור Singleton.
תארגנו את הקוד שלכם בשני קבצים:
ConfigManager.cs: צרו מחלקה בשםConfigManagerבמרחב השמותConfiguration, שמממשת את תבנית Singleton. מנהל התצורה שלכם צריך:- להכיל שדה סטטי פרטי שישמור את המופע היחיד
- להשתמש בבנאי פרטי כדי למנוע יצירת מופעים חיצונית
- לספק מאפיין סטטי
Instanceשמחזיר את המופע היחיד (השתמשו בגישה הפשוטה יותר של אתחול סטטי כדי להבטיח בטיחות בשימוש במקביל) - להכיל שדה מחרוזת פרטי
_appNameשמאותחל לערך"MyApp" - להכיל מתודה
SetAppName(string name)לעדכון שם היישום - להכיל מתודה
GetAppName()שמחזירה את שם היישום הנוכחי
Program.cs: בקובץ הראשי שלכם, הדגימו ש-Singleton פועל כראוי באמצעות גישה למופע כמה פעמים והצגה שהשינויים נשמרים בכל ההפניות.
תקבלו קלט אחד:
- שם יישום חדש להגדרה (לדוגמה,
ProductionServer)
בתוכנית שלכם:
- קבלו את המופע של
ConfigManagerוהדפיסו את שם היישום שמוגדר כברירת מחדל - קבלו שוב את המופע (לתוך משתנה אחר) והשתמשו בו כדי להגדיר את שם היישום החדש מהקלט
- קבלו את המופע בפעם השלישית והדפיסו את שם היישום כדי להוכיח שכל ההפניות חולקות את אותם נתונים
לדוגמה, אם הקלט הוא ProductionServer, הפלט צריך להיות:
MyApp
ProductionServerהדבר מדגים את היתרון המרכזי של Singleton — לא משנה כמה פעמים ניגשים אל Instance, תמיד מקבלים את אותו אובייקט עם מצב משותף. גישת האתחול הסטטי מבטיחה בטיחות בשימוש במקביל, מכיוון שה-CLR מבטיח שהשדה הסטטי מאותחל פעם אחת בלבד, גם אם כמה תהליכונים ניגשים אליו בו-זמנית.
נסו בעצמכם
using System;
using Configuration;
class Program
{
public static void Main(string[] args)
{
// קראו את הקלט - שם היישום החדש
string newAppName = Console.ReadLine();
// TODO: קבלו את המופע של ConfigManager והדפיסו את שם היישום המוגדר כברירת מחדל
// TODO: קבלו שוב את המופע (לתוך משתנה אחר) והשתמשו בו כדי להגדיר את שם היישום החדש
// TODO: קבלו את המופע בפעם השלישית והדפיסו את שם היישום כדי להוכיח שכל ההפניות חולקות את אותם נתונים
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמרחבי שמות והנחיותמבוא למחלקות ולאובייקטיםמילת המפתח 'this'מתודות ופרמטריםשדות לעומת מאפייניםבנאיםאתחול אובייקטיםסיכום – מחשבון פשוט4ירושה
תחביר ירושה בסיסית (:)מילת המפתח 'base'מילות המפתח Virtual ו-Overrideמחלקות Sealedמחלקת הבסיס 'object'סיכום – היררכיית עובדים7תכונות מתקדמות
העמסת אופרטוריםאינדקסרים (this[])דריסת ToString()מתודות הרחבהסיכום – רשימה מותאמת אישית10תבניות עיצוב חלק 1
מבוא לתבניות עיצובSingleton בטוח לריבוי תהליכוניםתבנית המפעלתבנית הצופה (אירועים)תבנית האסטרטגיה2מאפיינים וחברים סטטיים
מאפיינים במימוש אוטומטימאפיינים לקריאה בלבד ולכתיבה בלבדשדות ומתודות סטטייםמחלקות סטטיותחברים עם גוף ביטוי5פולימורפיזם וממשקים
פולימורפיזם בזמן קומפילציה לעומת בזמן ריצהממשק לעומת מחלקה מופשטתממשקים מרוביםממשקים מפורשיםהמרה כלפי מעלה והמרה כלפי מטהחזרה: מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה במקום ירושהGenerics (מחלקות ומתודות)נציגים ואירועיםמאפיינים ורפלקציהIDisposable והצהרת usingיסודות הזרקת תלויותתרגלו בעצמכם: קומפיילר C# אונליין