קבועים בג'אווה: דפוסים ואנטי דפוסים

1. הקדמה

במאמר זה נלמד על שימוש בקבועים בג'אווה תוך התמקדות בתבניות נפוצות ובתבניות אנטי.

נתחיל בכמה מוסכמות בסיסיות להגדרת קבועים. משם נעבור לעבר דפוסי אנטי נפוצים לפני שנסיים עם מבט על דפוסים נפוצים.

2. יסודות

קבוע הוא משתנה שערכו לא ישתנה לאחר שהוגדר.

בואו נסתכל על היסודות להגדרת קבוע:

סופי סטטי פרטי int OUR_CONSTANT = 1;

חלק מהדפוסים שנבדוק יתייחסו ל פּוּמְבֵּי אוֹ פְּרָטִי החלטת שינוי הגישה. אנחנו מכינים את הקבועים שלנו סטָטִי ו סופי ותן להם סוג מתאים, בין אם זה פרימיטיבי Java, מחלקה או enum. השם צריך להיות כל אותיות רישיות עם המילים המופרדות באמצעות קו תחתון, המכונה לפעמים כיסוי נחשים צורח. לבסוף, אנו מספקים את הערך עצמו.

3. אנטי דפוסים

ראשית, נתחיל בללמוד מה לא לעשות. בואו נסתכל על כמה אנטי-דפוסים נפוצים שאנחנו עשויים להיתקל בהם בעבודה עם קבועי Java.

3.1. מספרי קסם

מספרי קסם הם מילוליות מספריות בגוש קוד:

אם (number == 3.14159265359) {// ...}

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

3.2. כיתת קבועים עולמית גדולה

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

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

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

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

3.3. הממשק הקבוע נגד דפוס

דפוס הממשק הקבוע הוא כאשר אנו מגדירים ממשק המכיל את כל הקבועים לפונקציונליות מסוימת ואז יש לנו את הכיתות שזקוקות לפונקציות אלה כדי ליישם את הממשק.

בואו נגדיר ממשק קבוע למחשבון:

ממשק ציבורי מחשבון קבועים {PI כפול = 3.14159265359; כפול UPPER_LIMIT = 0x1.fffffffffffffP + 1023; מבצע "הוספה", הוצאה, מרובה, חלוקה}; }

לאחר מכן נבצע את היישום שלנו מחשבון קבועים מִמְשָׁק:

מחלקה ציבורית GeometryCalculator מיישמת CalculatorConstants {public double operationOnTwoNumbers (מספר כפול אחד, מספר כפול שני, פעולת פעולה) {// קוד לביצוע פעולה}}

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

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

גמר סטטי ציבורי כפול UPPER_LIMIT = 100000000000000000000.0;

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

טענה נוספת כנגד אנטי דפוס זה היא שהיא גורמת לזיהום מרחב השמות. שֶׁלָנוּ מחשבון קבועים כעת יהיה במרחב השמות של כל אחד מהשיעורים שלנו שמיישמים את הממשק, כמו גם כל אחת מתתי קבוצות המשנה שלהם.

4. דפוסים

מוקדם יותר בדקנו את הטופס המתאים להגדרת קבועים. בואו נסתכל על כמה שיטות עבודה טובות אחרות להגדרת קבועים ביישומים שלנו.

4.1. שיטות עבודה כלליות טובות

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

בואו נגדיר כמה קבועים ב- a מַחשְׁבוֹן מעמד:

מחשבון מחלקה ציבורית {ציבורי סופי סטטי ציבורי PI = 3.14159265359; כפול סופי סטטי פרטי UPPER_LIMIT = 0x1.fffffffffffffP + 1023; enum public מבצע {ADD, SUBTRACT, DIVIDE, MULTIPLY} public double operationOnTwoNumbers (double numberOne, double numberTwo, Operation operation) {if (numberOne> UPPER_LIMIT) {throw new IllegalArgumentException ("'numberOne' גדול מדי"); } אם (numberTwo> UPPER_LIMIT) {זרוק IllegalArgumentException חדש ("'numberTwo' גדול מדי"); } תשובה כפולה = 0; מתג (פעולה) {מקרה הוסף: תשובה = מספר אחד + מספר שני; לשבור; מקרה SUBTRACT: תשובה = numberOne - numberTwo; לשבור; מקרה DIVIDE: תשובה = מספר אחד / מספר שני; לשבור; מקרה מרובה: תשובה = מספר אחד * מספר שני; לשבור; } השיב תשובה; }}

בדוגמה שלנו הגדרנו קבוע עבור גבול עליון שאנחנו מתכננים להשתמש רק ב מַחשְׁבוֹן בכיתה, אז הגדרנו אותה ל פְּרָטִי. אנו רוצים שיעורים אחרים יוכלו להשתמש בהם פאי וה מבצע enum, אז הגדרנו את אלה ל פּוּמְבֵּי.

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

4.2. כיתת קבועים

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

בואו ניצור מתמטיקהקבועים מעמד:

כיתת גמר ציבורית מתמטיקהקבועים {גמר סטטי ציבורי כפול PI = 3.14159265359; כפול סופי סטטי GOLDEN_RATIO = 1.6180; כפול סופי סטטי GRAVITATIONAL_ACCELERATION = 9.8; כפול סופי סטטי EULERS_NUMBER = 2.7182818284590452353602874713527; enum public מבצע {ADD, SUBTRACT, DIVIDE, MULTIPLY} MathConstants פרטיים () {}}

הדבר הראשון שעלינו לשים לב אליו הוא זה הכיתה שלנו היא סופי כדי למנוע את הארכתו. בנוסף, הגדרנו א פְּרָטִי קונסטרוקטור כך שאי אפשר לייצר אותו. לבסוף, אנו יכולים לראות כי יישמנו את שיטות העבודה הטובות האחרות עליהם דנו קודם במאמר. הקבוע שלנו פאי הוא פּוּמְבֵּי כי אנו צופים צורך לגשת אליו מחוץ לחבילה שלנו. שאר הקבועים שהשארנו בתור חבילה-פרטיתכדי שנוכל לגשת אליהם במסגרת החבילה שלנו. יצרנו את כל הקבועים שלנו סטָטִי ו סופי וקרא להם בתיק נחשים צורח. הפעולות הן קבוצה ספציפית של ערכים, לכן השתמשנו ב- enum להגדיר אותם.

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

5. מסקנה

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

כמו תמיד הקוד ניתן להשיג ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found