
מה זה סינגלטון בג'אווה?
Singleton הוא אחד מדפוסי העיצוב הפשוטים ביותר ברמת הכיתה. לפעמים אנשים אומרים "מחלקה זו היא יחידה", כלומר המחלקה מיישמת את תבנית עיצוב הסינגלטון. לפעמים יש צורך לכתוב מחלקה שבה אנו מגבילים מופע לאובייקט בודד. לדוגמה, מחלקה האחראית על רישום או התחברות ל- מסד נתונים. דפוס עיצוב הסינגלטון מתאר כיצד אנו יכולים להשיג זאת. סינגלטון הוא דפוס עיצוב שעושה שני דברים:-
זה מבטיח שאי פעם יהיה רק מופע אחד של הכיתה.
-
הוא מספק נקודת גישה גלובלית אחת לאותו מופע.
-
בנאי פרטי. זה מגביל את היכולת ליצור אובייקטים של המחלקה מחוץ למחלקה עצמה.
-
שיטה סטטית ציבורית שמחזירה את המופע של המחלקה. שיטה זו נקראת getInstance . זוהי נקודת הגישה הגלובלית למופע המחלקה.
אפשרויות יישום
דפוס עיצוב הסינגלטון מיושם בדרכים שונות. כל אפשרות טובה ורעות בדרכה. כמו תמיד, אין כאן אפשרות מושלמת, אבל עלינו לשאוף לאחת. קודם כל, בואו נחליט מה נחשב טוב ורע, ואילו מדדים משפיעים על האופן שבו אנו מעריכים את המימושים השונים של דפוס העיצוב. נתחיל מהטוב. להלן גורמים שהופכים את היישום לעסיסי ומושך יותר:-
אתחול עצלן: המופע לא נוצר עד שיש צורך בו.
-
קוד פשוט ושקוף: המדד הזה, כמובן, הוא סובייקטיבי, אבל הוא חשוב.
-
בטיחות חוטים: פעולה נכונה בסביבה מרובת חוטים.
-
ביצועים גבוהים בסביבה מרובה הליכי: חסימת חוטים מועטה או ללא חסימת חוטים בעת שיתוף משאב.
-
ללא אתחול עצלן: כאשר המחלקה נטענת כאשר האפליקציה מתחילה, ללא קשר אם יש צורך בה או לא (באופן פרדוקסלי, בעולם ה-IT עדיף להתעצל)
-
קוד מורכב וקשה לקריאה. מדד זה הוא גם סובייקטיבי. אם העיניים שלך מתחילות לדמם, נניח שהיישום אינו הטוב ביותר.
-
חוסר בטיחות חוטים. במילים אחרות, "סכנת חוט". פעולה שגויה בסביבה מרובת חוטים.
-
ביצועים גרועים בסביבה מרובת חוטים: שרשורים חוסמים זה את זה כל הזמן או לעתים קרובות בעת שיתוף משאב.
קוד
כעת אנו מוכנים לשקול אפשרויות יישום שונות ולציין את היתרונות והחסרונות:פָּשׁוּט
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
היישום הפשוט ביותר. יתרונות:
-
קוד פשוט ושקוף
-
בטיחות חוטים
-
ביצועים גבוהים בסביבה מרובת חוטים
- אין אתחול עצלן.
אתחול עצלן
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
יתרונות:
-
אתחול עצלן.
-
לא בטוח בשרשור
גישה מסונכרנת
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
יתרונות:
-
אתחול עצלן.
-
בטיחות חוטים
-
ביצועים גרועים עם ריבוי חוטים
נעילה בבדיקה כפולה
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
יתרונות:
-
אתחול עצלן.
-
בטיחות חוטים
-
ביצועים גבוהים בסביבה מרובת חוטים
-
לא נתמך בגרסאות קודמות של Java מתחת ל-1.5 (השימוש במילת מפתח נדיפה קבוע מאז גרסת 1.5)
בעל כיתה
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
יתרונות:
-
אתחול עצלן.
-
בטיחות חוטים.
-
ביצועים גבוהים בסביבה מרובת חוטים.
-
פעולה נכונה דורשת ערובה לכך שאובייקט הסינגלטון מאותחל ללא שגיאות. אחרת, הקריאה הראשונה למתודה getInstance תגרום ל- ExceptionInInitializerError , וכל הקריאות הבאות יפיקו NoClassDefFoundError .
יישום | אתחול עצלן | בטיחות חוטים | ביצועים מרובים | מתי להשתמש? |
---|---|---|---|---|
פָּשׁוּט | - | + | מָהִיר | לעולם לא. או אולי כאשר אתחול עצלן אינו חשוב. אבל לעולם לא יהיה טוב יותר. |
אתחול עצלן | + | - | לא ישים | תמיד כאשר אין צורך בריבוי השחלות |
גישה מסונכרנת | + | + | לְהַאֵט | לעולם לא. או אולי כאשר אין חשיבות לביצועים עם ריבוי חוטים. אבל לעולם לא יהיה טוב יותר. |
נעילה בבדיקה כפולה | + | + | מָהִיר | במקרים נדירים כאשר אתה צריך לטפל בחריגים בעת יצירת הסינגלטון (כאשר הסינגלטון בעל הכיתה אינו ישים) |
בעל כיתה | + | + | מָהִיר | בכל פעם שיש צורך בריבוי השחלות ויש ערובה שאובייקט הסינגלטון ייווצר ללא בעיות. |
יתרונות וחסרונות של דפוס הסינגלטון
באופן כללי, סינגלטון עושה בדיוק מה שמצפים ממנו:-
זה מבטיח שאי פעם יהיה רק מופע אחד של הכיתה.
-
הוא מספק נקודת גישה גלובלית אחת לאותו מופע.
-
יחידה מפרה את עקרון האחריות היחידה: בנוסף לחובותיו הישירות, מחלקה יחידנית שולטת גם במספר המקרים.
-
התלות של כיתה רגילה ביחיד לא נראית בחוזה הציבורי של הכיתה.
-
משתנים גלובליים גרועים. בסופו של דבר, יחיד הופך למשתנה גלובלי כבד.
-
הנוכחות של סינגלטון מפחיתה את יכולת הבדיקה של האפליקציה בכללותה ואת המחלקות המשתמשות בסינגלטון בפרט.
GO TO FULL VERSION