Singleton DP

  • פותח הנושא TTTIS
  • פורסם בתאריך

TTTIS

New member
Singleton DP

מתי נכון להשתמש ב-Singleton DP? מתי נכון לעשות אותו thread-safety? מה קורה כשמבתצעות שתי קריאות למתודה באינסטנס בו זמנית? מה היתרון בשימוש בתבנית מול Database? האם מומלץ לממש בכדי ליצור חיבור אחד?
 

עידו פ

New member
-->

סינגלטון מיועד כאשר אתה רוצה להיות בשליטה על כמות הגישות למשאב. הדוגמה הנפוצה - כאשר אתה רוצה ליצור קובץ לוג ואתה נאלץ להשתמש ב-Handler אחד לקובץ, תרצה ליצור מצב בו קיים רק Instance אחד של רכיב הגישה ללוג. דוגמה נוספת - כאשר רוצים להגביל את כמות הגישות משאב (דוגמת DB) - ניתן להגדיר סינגלטון שמאפשר יצירה של עד X מופעים של המחלקה ולהחזיר אותם בהתאם לצורך בהם. לגבי thread safety - אני משער שאתה מדבר על דוטנט, אז אני אמליץ שתשאל את זה בפורום דוט נט (כנ"ל לגבי השאלה השלישית). שימוש בתבנית מול DB ? בעיקרון אין צורך להתקמצן בגישות ל-DB (בהנחה ומדובר ב-DB נורמלי שתומך בריבוי גישות). אבל בשביל תשובה הולמת צריך לדעת יותר פרטים כגון באיזה סביבת פיתוח מדובר, האם שקלת שימוש במנגנונים לניהול גישות ל-DB (אם הבנתי נכון אתה עובד בדוטנט, האם שקלת להשתמש ב-COM+ ?)
 

TTTIS

New member
תגובה

קודם תודה, הבנתי לפי הדוגמא של הלוג. אני משתמש ב-DB של אורקל. אני יודע שהוא מנהל איזשהו Connection Pooling אז אולי במקרה שלי זה מיותר לעשות Singleton לרכיב DAL. שאלתי גם בפורום דוט נט אבל לא נתנו לי שם תשובות מספקות. חשוב לי לדעת את התשובה לשאלה השלישית. בהנחה ולא מדובר בדוט נט, מה אז תהיה התשובה?
 
תשובה

קודם כל, העניין עם הSingleton מתאים גם לג'אווה, C/C++ ועוד שפות. Singleton משמש גם למקרה שרוצים אובייקט אחד שכולם פונים אליו. הדוגמא שאני יכול לתת שהשתמשתי בה בעבר זה מנגנון Cache: יש אובייקט אחד ששומר מידע של Cache בזיכרון, וכל הבקשות מופנות אליו. לאובייקטים כאלה יש נטייה לבעיות כשעובדים עם שרתים מבוזרים. כשיש שרתי ראי שמחלקים את העומס, אז צריך אובייקט אחד בכל שרת וכל אובייקט מתמלא במידע אחר בקיצור - בלאגן רציני. לעניין האוראקל: זה תלוי. אם המשתמשים ניגשים ישירות לשרת, כלומר על כל מחשב של כל משתמש מותקן Oracle client, ועלול להיות מצב שאלפי משתמשים יגשו בו זמנית, יש מקום לתכנן רכיב כזה. אבל אם מדובר במצב הנפוץ, בו הגישה לאוראקל נעשית דרך שרת Web (כמו IIS במקרה של .NET) אז לא צריכה להיות שום בעיה, כי השרת עצמו לא פותח Thread לכל משתמש, אלא יש לו pooling משלו ולא יהיה מצב של אלפי משתמשים על הDB. כך או כך, מומלץ להשתמש כמה שיותר במנגנונים של השרתים ה"מקצועיים" כלומר האוראקל עצמו, ולא לכתוב רכיבים כאלה בעצמך. ברוב המקרים, האופטימיזציה של השרתים יודעים מראש לטפל במצבי עומס עם מקנפגים אותם כראוי, והקוד שלך לעומת זאת עלול להיות פגיע יותר.
 

ייוניי

New member
Singleton

אנסה לענות על הכל: 1. Singleton הוא DP חשוב אך גם מסוכן מאוד ולכן מומלץ להשתמש בו רק במקרים מאוד מסויימים. המטרה היא כמובן לשפר ביצועים ולרכז גישה למשאבים שונים. הטעות הנפוצה היא השימוש ב Singleton כפתרון קל לגישה לאובייקט בצורה סטטית מכל רחבי האפליקציה. בתור התחלה הייתי מגביל את השימוש ב Singleton למחלקות שהטעינה שלהן כבדה או למחלקות המשתמשות במשאבי מערכת שצריך לרכז את הגישה אליהם. 2. לדעתי כמעט תמיד. האמת היא שמבחינתי כל מחלקה שמכבדת את עצמה צריכה להיות thread safe כי אתה באמת לא יכול לדעת מתי תרצה להשתמש ב multithreading באפליקציה. מחלקות Singleton שמשתמשות במשאבים על אחת כמה וכמה. 3. מה קורה? המתודה רצה פעמיים בו זמנית! אם המתודה שלך כותבת Hellow World לקונסול אין לך בעיה כי זה פשוט ייכתב פעמיים. אבל אם המתודה שלך בודקת אם משתנה מחלקה שווה ל null ואם לא אז עושה איתו משהו ומעדכנת אותו ל null אז אתה בבעיה מפני שבזמן שמתודה אחת מעדכנת ל null השניה יכולה להגיע לשורה שמבצעת פעולה וליפול על NullReferenceException. בדיוק למקרים כאלו נועדה הפקודה lock שלא מאפשרת לשני thread-ים להריץ קטע קוד מסויים בו זמנית. 4. זו שאלה טכנית והתשובה שונה עבור כל DBMS אבל על פניו זה נראה שימוש לגיטימי כי בד"כ אובייקטים שקשורים ל DBMS הם יקרים ליצירה וניתן לרכז גישה אליהם בצורה די פשוטה.
 
למעלה