מבוא לדפוסי עיצוב יצירה

1. הקדמה

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

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

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

2. דפוסי עיצוב יצירה

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

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

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

במאמר זה נדון בארבעה סוגים של דפוס עיצוב יצירתי:

  1. Singleton - מבטיח כי לכל היותר מופע אחד בלבד של אובייקט קיים לאורך היישום
  2. שיטת מפעל - יוצר אובייקטים ממספר מחלקות קשורות מבלי לציין את האובייקט המדויק שייווצר
  3. מפעל מופשט - יוצר משפחות של אובייקטים תלויים הקשורים
  4. בּוֹנֶהבונה אובייקטים מורכבים באמצעות גישה שלב אחר שלב

בואו ונדון בפירוט בכל אחד מהדפוסים הללו.

3. דפוס עיצוב סינגלטון

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

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

3.1. דוגמה לתבנית סינגלטון

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

אז הנה, אנו הולכים לפי גישה אופטימלית יותר העושה שימוש במעמד פנימי סטטי:

מחלקה ציבורית Singleton {Private Singleton () {} class static private SingletonHolder {מופע סופי ציבורי סטטי סינגלטון = Singleton חדש (); } סינגלטון סטטי ציבורי getInstance () {return SingletonHolder.instance; }}

הנה, יצרנו סטָטִי מעמד פנימי המחזיק במופע של קְלָף בּוֹדֵד מעמד. זה יוצר את המופע רק כאשר מישהו מתקשר אל getInstance () שיטה ולא כאשר המחלקה החיצונית נטענת.

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

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

זכור, זה לא היישום המקורי של GoF. לקבלת הגרסה המקורית, בקר במאמר המקושר של Baeldung בנושא Singletons ב- Java.

3.2. מתי להשתמש בתבנית העיצוב של סינגלטון

  • עבור משאבים יקרים ליצירה (כמו אובייקטים לחיבור מסד נתונים)
  • זה נוהג טוב לשמור על כל חוטבי הלוגר כ- Singletons מה שמגדיל את הביצועים
  • שיעורים המספקים גישה להגדרות התצורה של היישום
  • שיעורים המכילים משאבים אליהם ניתן לגשת במצב משותף

4. תבנית עיצוב שיטת מפעל

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

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

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

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

4.1. דוגמה לתבנית עיצוב שיטת מפעל

בדוגמה זו ניצור א מְצוּלָע ממשק אשר יושם על ידי כמה כיתות קונקרטיות. א PolygonFactory ישמש להבאת חפצים ממשפחה זו:

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

ממשק ציבורי מצולע {String getType (); }

לאחר מכן, ניצור כמה יישומים כמו כיכר, משולש, וכו 'המיישמים ממשק זה ומחזירים אובייקט של מְצוּלָע סוּג.

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

מחלקה ציבורית PolygonFactory {PolygonFactory public getPolygon (int numberOfSides) {if (numberOfSides == 3) {להחזיר משולש חדש (); } אם (numberOfSides == 4) {להחזיר ריבוע חדש (); } אם (numberOfSides == 5) {להחזיר פנטגון חדש (); } אם (numberOfSides == 7) {להחזיר את הפטגון החדש (); } אחרת אם (numberOfSides == 8) {להחזיר אוקטגון חדש (); } להחזיר אפס; }}

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

4.2. מתי להשתמש בתבנית עיצוב שיטת המפעל

  • כאשר יישום ממשק או מעמד מופשט צפוי להשתנות לעיתים קרובות
  • כאשר היישום הנוכחי אינו יכול להכיל בנוחות שינוי חדש
  • כאשר תהליך האתחול פשוט יחסית, והבנאי דורש רק קומץ פרמטרים

5. דפוס עיצוב מפעל מופשט

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

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

לקבלת הסבר מפורט, עיין במדריך שלנו למפעל מופשט.

6. תבנית עיצוב בנאי

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

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

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

6.1. דוגמה לתבנית תבנית בונה

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

ג'ושוע בלוך, בספרו Effective Java, הציג גרסה משופרת של תבנית הבנאי שהיא נקייה, קריאה מאוד (מכיוון שהיא עושה שימוש בעיצוב שוטף) ונוחה לשימוש מנקודת מבט הלקוח. בדוגמה זו נדון בגרסה זו.

לדוגמא זו יש רק מחלקה אחת, חשבון בנק המכיל בונה כ- סטָטִי מעמד פנימי:

מעמד ציבורי BankAccount {שם מחרוזת פרטי; חשבון מחרוזת פרטי מספר; דוא"ל מחרוזת פרטי; עלון בוליאני פרטי; // בונים / גטרים מחלקה סטטית ציבורית BankAccountBuilder {// קוד בונה}} 

שים לב שכל מכניסי הגישה בשדות מוצהרים פְּרָטִי מכיוון שאיננו רוצים שחפצים חיצוניים ייגשו אליהם ישירות.

הקונסטרוקטור הוא גם כן פְּרָטִי כך שרק הבנאי שהוקצה לכיתה זו יוכל לגשת אליו. כל המאפיינים שנקבעו בבנאי מופקים מאובייקט הבנאי אותו אנו מספקים כארגומנט.

הגדרנו BankAccountBuilder ב סטָטִי מעמד פנימי:

מחלקה סטטית ציבורית BankAccountBuilder {שם מחרוזת פרטי; חשבון מחרוזת פרטי מספר; דוא"ל מחרוזת פרטי; עלון בוליאני פרטי; BankAccountBuilder ציבורי (שם מחרוזת, מחרוזת חשבון מספר) {this.name = שם; this.accountNumber = accountNumber; } BankAccountBuilder ציבורי עם דואר אלקטרוני (מייל מחרוזת) {this.email = דוא"ל; להחזיר את זה; } עלון ציבורי של BankAccountBuilder (עלון בוליאני) {this.newsletter = newsletter; להחזיר את זה; } בניית BankAccount ציבורית () {החזר BankAccount חדש (זה); }} 

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

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

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

בואו נראה דוגמה מהירה לדפוס הבנאי בפעולה:

BankAccount newAccount = חדש BankAccount .BankAccountBuilder ("Jon", "22738022275") .withEmail ("[email protected]") .wantNewsletter (true) .build ();

6.2. מתי להשתמש בתבנית בונה

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

7. מסקנה

במאמר זה למדנו על דפוסי עיצוב יצירתיים בג'אווה. דנו גם בארבעת הסוגים השונים שלהם, כלומר Singleton, Factory Method, Abstract Factory ו- Builder Pattern, היתרונות שלהם, דוגמאות ומתי עלינו להשתמש בהם.

כמו תמיד, קטעי הקוד המלאים זמינים ב- GitHub.


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