CodeGym /בלוג Java /Random-HE /דפוסים וסינגלטון בג'אווה
John Squirrels
רָמָה
San Francisco

דפוסים וסינגלטון בג'אווה

פורסם בקבוצה
מאמר זה פונה לכל מי שנתקל בפעם הראשונה במושג דפוסי עיצוב, שמע את המושג singleton או יישם איכשהו את דפוס הסינגלטון אבל לא הבין מה קורה. ברוך הבא! תלמידי CodeGym נתקלים בדפוסי עיצוב בפעם הראשונה ברמה 15, כאשר הקפטן מבקש מהם במפתיע "לחזק" את הבנתם על ידי יישום דפוס Java Singleton עם יישום עצלן. לסטודנטים ששומעים על דפוס הסינגלטון בפעם הראשונה יש הרבה שאלות: מה זה בכלל דפוס עיצובי? למה אנחנו צריכים את זה? מה זה סינגלטון ? ולבסוף, מהו יישום עצלן? בואו נענה על השאלות האלה לפי הסדר.

מה זה בכלל דפוס עיצובי?

אני מאמין שמעט היסטוריה נועדה לענות על שאלה זו בהבנה הטובה ביותר. ישנם ארבעה מחברי תכנות מפורסמים (אריך גמא, ג'ון וליסיידס, ראלף ג'ונסון וריצ'רד הלם) שהעלו רעיון מעניין. הם שמו לב שלעתים קרובות פיתוח תוכנה מחייב אותם לפתור את אותן בעיות בערך ולכתוב קוד מובנה באותו אופן. אז הם החליטו לתאר דפוסים טיפוסיים שלעיתים קרובות צריך להשתמש בהם בתכנות מונחה עצמים. ספרם פורסם בשנת 1994 תחת הכותרת Design Patterns: Elements of Reusable Object-Oriented Software. השם של הספר התברר כארוך מדי ואנשים התחילו לקרוא לו פשוט הספר של כנופיית הארבעה. המהדורה הראשונה כללה 23 דפוסים. לאחר מכן, התגלו עשרות דפוסים אחרים. אז הבה נסכם את התשובה לשאלה של הפסקה הזו (מהן בכלל דפוסי עיצוב?) בכמה מילים:
תבנית עיצוב היא פתרון סטנדרטי לבעיה נפוצה.
ודפוס הסינגלטון הוא רק אחד מהם.

למה אנחנו צריכים דפוסי עיצוב?

אתה יכול לתכנת בלי לדעת דפוסים: אחרי הכל, עד רמה 15, כבר כתבת מאות מיני תוכניות ב-CodeGym בלי לדעת בכלל שהן קיימות. זה מצביע על כך שדפוסי עיצוב הם סוג של כלי שהשימוש בו מבדיל את המאסטר מהחובב: דפוסי עיצוב מתארים כיצד לפתור בעיה טיפוסית בצורה נכונה. המשמעות היא שהכרת דפוסים חוסכת לך זמן. בדרך זו, הם דומים לאלגוריתמים. לדוגמה, אתה יכול ליצור אלגוריתם מיון משלך עם בלאק ג'ק ומספרים ולהקדיש זמן רב לכך, או שאתה יכול ליישם אחד שהובן ותואר במשך זמן רב. אותו הדבר נכון עם דפוסי עיצוב. בנוסף, עם דפוסי עיצוב, הקוד הופך לסטנדרטי יותר, וכאשר משתמשים בדפוס המתאים, יש פחות סיכוי שתעשה טעויות, מכיוון שהמלכודות הנפוצות של הדפוס זוהו והוסרו לפני זמן רב. בנוסף לכל השאר, הכרת דפוסים עוזרת למתכנתים להבין זה את זה טוב יותר. אתה יכול פשוט לומר את שם התבנית במקום לנסות לספק הסבר ארוך לעמיתיך המתכנתים. לסיכום, דפוסי עיצוב עוזרים לך:
  • לא להמציא את הגלגל מחדש, אלא להשתמש בפתרונות סטנדרטיים;
  • תקן קוד;
  • סטנדרטיזציה של טרמינולוגיה;
לסיום סעיף זה, נציין שניתן לחלק את כל גוף דפוסי העיצוב לשלוש קבוצות גדולות: דפוסים וסינגלטון - לכל מי שנתקל בהם בפעם הראשונה - 2

לבסוף, דפוס הסינגלטון

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

  2. כאשר אתה צריך לספק נקודה לגישה גלובלית לאובייקט. במילים אחרות, עליך להפוך את האובייקט לזמין מכל מקום בתוכנית. למרבה הצער, זה לא מספיק פשוט ליצור משתנה גלובלי, מכיוון שהוא אינו מוגן כתיבה: כל אחד יכול לשנות את ערך המשתנה, כך שנקודת הגישה הגלובלית של האובייקט עלולה ללכת לאיבוד. מאפיינים אלה של Singleton נחוצים, למשל, כאשר יש לך אובייקט שעובד עם מסד נתונים, ואתה צריך לגשת למסד הנתונים מחלקים שונים של התוכנית. Singleton יבטיח שאף אחד לא יכתוב קוד שמחליף את המופע שנוצר קודם לכן .
אז סינגלטון סיפק את שני הצרכים האלה: חייב להיות רק אחד מסוג מסוים של אובייקט בתוכנית וחייבת להיות גישה גלובלית אליו. בדוגמה ברמה 15, הקפטן מבקש ממך ליישם את הדפוס הזה עבור המשימה הבאה:
  1. מצא דוגמה לסינגלטון עם אתחול עצלן.

  2. צור שלושה מחלקות יחיד - שמש, ירח, כדור הארץ - בקבצים נפרדים תוך שימוש באותו עיקרון.

  3. ליישםכוכב לכתממשק בכיתות שמש , ירח וכדור הארץ .

  4. בבלוק סטטי של המחלקה Solution קרא אתreadKeyFromConsoleAndInitPlanetשיטה.

  5. יישם אתreadKeyFromConsoleAndInitPlanetפונקציונליות השיטה:

    • 5.1. קרא פרמטר מחרוזת אחד מהמסוף

    • 5.2. אם הפרמטר שווה לאחד מה-כוכב לכתהקבועים של הממשק, צור את אובייקט ה-Planet מתאים .

לאחר שקראנו בקפידה את תנאי המשימה, אנו יכולים לראות בבירור מדוע יש צורך בסינגלטון כאן. ואכן, אנו מתבקשים ליצור מופע של כל אחת מהמחלקות הבאות: שמש , ירח , כדור הארץ . הגיוני להניח שעלינו ליצור לא יותר משמש/ירח/כדור הארץ אחד. אחרת, אנחנו נקלעים למצב אבסורדי, אלא אם כמובן אתה כותב את הגרסה שלך למלחמת הכוכבים. הטמעת דפוס הסינגלטון ב-Java בשלושה שלבים ב-Java, לא ניתן ליישם התנהגות Singleton באמצעות בנאי רגיל, מכיוון שבנאי תמיד מחזיר אובייקט חדש. לכן, כל ההטמעות של Singleton מסתכמת בהסתרת הקונסטרוקטור, יצירת שיטה סטטית ציבורית השולטת בחייו של אובייקט הסינגלטון, ו"השמדת" כל האובייקטים החדשים שהופיעו. אם ניגשים ל- Singleton , עליו ליצור אובייקט חדש (אם אחד לא קיים כבר בתוכנית), או להחזיר אובייקט קיים. להשיג את זה:
  1. אתה צריך לתת למחלקה שדה סטטי פרטי המאחסן אובייקט בודד:

    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
  2. הפוך את הבנאי (ברירת המחדל) לפרטי. המשמעות היא שלא ניתן לגשת אליו מחוץ למחלקה ולא תוכל להחזיר אובייקטים חדשים:

    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    }
  3. הכריז על שיטת יצירה סטטית שתשמש לקבלת הסינגלטון:

    public class LazyInitializedSingleton {
        private static LazyInitializedSingleton instance;
            private LazyInitializedSingleton() {}
            public static LazyInitializedSingleton getInstance() { // #3
            if (instance == null) { // If the object has not yet been created
                instance = new LazyInitializedSingleton(); // Create a new object
            }
            return instance; // Return the previously created object
        }
    }
הדוגמה לעיל היא מעט מגושמת, מכיוון שאנו פשוט מסתירים את הבנאי ומספקים שיטה משלנו במקום בנאי סטנדרטי. מכיוון שמאמר זה נועד להבטיח שתלמידי CodeGym יבואו במגע עם דפוס זה (ודפוסי עיצוב בכלל), הניואנסים של יישומי יחיד מורכבים יותר לא יתוארו כאן. נציין רק כי בהתאם למורכבות התוכנית, ייתכן שיהיה צורך לשכלל עוד יותר דפוס זה. לדוגמה, בסביבת ריבוי חוטים (ראה מאמרים על שרשורים), מספר שרשורים שונים עשויים לגשת לשיטת הסינגלטון בו-זמנית, והקוד המתואר לעיל יפסיק לעבוד, מכיוון שכל שרשור נפרד יכול ליצור מופע של המחלקה. כתוצאה מכך, עדיין קיימות מספר גישות שונות ליצירת סינגלונים מתאימים לבטיחות חוט. אבל זה כבר סיפור אחר =)

ולבסוף... מה זה האתחול העצל הזה שעליו שאל הקפטן?

אתחול עצלן נקרא גם אתחול דחוי. זהו טריק תכנות שבו פעולה עתירת משאבים (ויצירת אובייקט היא פעולה עתירת משאבים) מתבצעת על פי דרישה ולא מראש. אז מה בעצם קורה בקוד ה- Singleton Java שלנו? במילים אחרות, האובייקט שלנו נוצר בזמן הגישה אליו, לא מראש. אתה לא צריך להניח שאתחול עצלן קשור איכשהו בצורה נוקשה לתבנית הסינגלטון . אתחול עצלן משמש גם בדפוסי עיצוב יצירתיים אחרים, כמו Proxy ו-Factory Method, אבל זה גם סיפור אחר =)
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION