ייצור אוטומטי של תבנית הבנאי עם FreeBuilder

1. סקירה כללית

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

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

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

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

3. יישום Builder בג'אווה

לפני שנמשיך עם FreeBuilder, בואו נבצע בניית boilerplate עבורנו עוֹבֵד מעמד:

שכבה ציבורית שכיר {פרטי סופי שם מחרוזת; גיל פרטי פרטי סופי; מחלקת מחרוזת סופית פרטית; עובד פרטי (שם מחרוזת, גיל int, מחלקת מחרוזות) {this.name = שם; this.age = גיל; זו.מחלקה = מחלקה; }}

ופנימי בּוֹנֶה מעמד:

מחלקה סטטית ציבורית בונה {שם מחרוזת פרטי; גיל פרטי פרטי; מחלקת מיתרים פרטית; public Builder setName (שם מחרוזת) {this.name = שם; להחזיר את זה; } בנאי ציבורי setAge (int age) {this.age = age; להחזיר את זה; } בנאי ציבורי setDepartment (מחלקת מחרוזות) {this.department = מחלקה; להחזיר את זה; } בניין עובד ציבורי () {החזר עובד חדש (שם, גיל, מחלקה); }}

לפיכך, כעת אנו יכולים להשתמש בבונה לצורך הפעלה מיידית של ה- עוֹבֵד לְהִתְנַגֵד:

Employee.Builder emplBuilder = Employee.Builder חדש (); עובד שכיר = emplBuilder .setName ("baeldung") .setAge (12) .setDepartment ("תבנית בנאי") .build ();

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

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

4. תלות של Maven

כדי להוסיף את ספריית FreeBuilder, נוסיף את התלות FreeBuilder Maven בתוכנה שלנו pom.xml:

 בונה חופשי של org. 2.4.1 

5. FreeBuilder ביאור

5.1. יצירת בונה

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

נו ביאור שלנו עוֹבֵד מהסעיף הקודם עם @FreeBuilderוראה כיצד הוא יוצר באופן אוטומטי את מחלקת הבונים:

ממשק ציבורי @FreeBuilder עובד {שם מחרוזת (); גיל int (); מחלקת מיתרים (); Class Builder מרחיב את Employee_Builder {}}

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

לפני שנמשיך להשתמש בבונה זה, עלינו להגדיר את ה- IDEs שלנו כדי להימנע מבעיות אוסף. מאז FreeBuilder מייצר באופן אוטומטי את עובד_בנאי שיעור במהלך ההידור, ה- IDE בדרך כלל מתלונן על ClassNotFoundException בשורה מספר 8.

כדי להימנע מבעיות כאלה, עלינו לאפשר עיבוד הערות ב- IntelliJ או Eclipse. ותוך כדי כך נשתמש במעבד ההערות של FreeBuilder org.inferred.freebuilder.processor.Processor. בנוסף, יש לסמן את הספריה המשמשת ליצירת קבצי מקור אלה כ- Root Sources.

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

לבסוף, ערכנו את הפרויקט שלנו וכעת נוכל להשתמש ב- עובד. בונה מעמד:

Employee.Builder builder = Employee.Builder חדש (); עובד שכיר = builder.name ("baeldung") .age (10) .department ("תבנית בונה") .build ();

בסך הכל, ישנם שני הבדלים עיקריים בין זה לבין מעמד הבנאי שראינו קודם. ראשון, עלינו לקבוע את הערך לכל התכונות של ה- עוֹבֵד מעמד. אחרת, זה זורק IllegalStateException.

נראה כיצד FreeBuilder מטפל בתכונות אופציונליות בחלק מאוחר יותר.

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

5.2. ועידת שמות JavaBean

כדי לאכוף את FreeBuilder לפעול על פי אמנת השמות JavaBean, עלינו לעשות זאת שנה את שם השיטות שלנו ב עוֹבֵד וקידם את השיטות עם לקבל:

ממשק ציבורי @FreeBuilder עובד {String getName (); int getAge (); מחרוזת getDepartment (); Class Builder מרחיב את Employee_Builder {}}

פעולה זו תיצור קבצים וקובעים העוקבים אחר מוסכמת שמות JavaBean:

עובד שכיר = builder .setName ("baeldung") .setAge (10) .setDepartment ("תבנית בונה") .build ();

5.3. שיטות Mapper

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

נניח שלנו עוֹבֵד בכיתה יש גם תחום שכר:

ממשק ציבורי @FreeBuilder עובד {אופציונלי getSalaryInUSD (); }

נניח שעלינו להמיר את מטבע המשכורת המסופק כקלט:

משכורת ארוכהInEuros = INPUT_SALARY_EUROS; Employee.Builder builder = Employee.Builder חדש (); עובד שכיר = builder .setName ("baeldung") .setAge (10) .mapSalaryInUSD (sal -> salaryInEuros * EUROS_TO_USD_RATIO) .build ();

FreeBuilder מספק שיטות מיפוי כאלה לכל התחומים.

6. ערכי ברירת מחדל ובדיקות אילוצים

6.1. הגדרת ערכי ברירת מחדל

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

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

אנו יכולים להגדיר ערכי ברירת מחדל ב- עובד. בונה בַּנַאִי:

@FreeBuilder ממשק ציבורי עובד {// getter שיטות מחלקה Builder מרחיב Employee_Builder {public Builder () {setDepartment ("תבנית בונה"); }}}

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

6.2. בדיקות אילוצים

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

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

@FreeBuilder ממשק ציבורי עובד {// getter שיטות בכיתה Builder מרחיב Employee_Builder {@Override Public Builder setEmail (מייל מחרוזת) {אם (checkValidEmail (דוא"ל)) להחזיר super.setEmail (דוא"ל); אחרת לזרוק IllegalArgumentException חדש ("דוא"ל לא חוקי"); } check בוליאני פרטי ValidEmail (מייל מחרוזת) {return email.contains ("@"); }}}

7. ערכים אופציונליים

7.1. באמצעות אופציונאלי שדות

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

ממשק ציבורי @FreeBuilder עובד {String getName (); int getAge (); // getters אחרים אופציונלי getPermanent (); אופציונלי getDateOfJoining (); Class Builder מרחיב את Employee_Builder {}}

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

עובד שכיר = builder.setName ("baeldung") .setAge (10) .setPermanent (true) .build ();

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

7.2. באמצעות @מאפשרת ערכי null שדות

למרות שימוש אופציונאלי מומלץ לטיפול ריקב- Java, FreeBuilder מאפשר אותנו להשתמש @מאפשרת ערכי null לתאימות לאחור:

ממשק ציבורי @FreeBuilder עובד {String getName (); int getAge (); // שיטות אחרות של גטר אופציונלי getPermanent (); אופציונלי getDateOfJoining (); מחרוזת @ Nullable getCurrentProject (); Class Builder מרחיב את Employee_Builder {}}

השימוש של אופציונאלי אינו מומלץ במקרים מסוימים וזו סיבה נוספת לכך @מאפשרת ערכי null מועדף לשיעורי בנאי.

8. אוספים ומפות

ל- FreeBuilder תמיכה מיוחדת באוספים ומפות:

ממשק ציבורי @FreeBuilder עובד {String getName (); int getAge (); // שיטות אחרות של getter רשימת getAccessTokens (); מפה getAssetsSerialIdMapping (); Class Builder מרחיב את Employee_Builder {}}

מוסיף FreeBuilder שיטות נוחות להוספת אלמנטים קלט לאוסף במחלקת הבונים:

עובד שכיר = builder.setName ("baeldung") .setAge (10) .addAccessTokens (1221819L) .addAccessTokens (1223441L, 134567L) .build ();

יש גם getAccessTokens () שיטה בכיתת הבנאי אשר מחזירה רשימה שלא ניתנת לשינוי. באופן דומה, עבור מַפָּה:

עובד שכיר = builder.setName ("baeldung") .setAge (10) .addAccessTokens (1221819L) .addAccessTokens (1223441L, 134567L) .putAssetsSerialIdMapping ("מחשב נייד", 12345L) .build ();

ה גטר שיטה עבור מַפָּה גַם מחזירה מפה שלא ניתנת לשינוי לקוד הלקוח.

9. בונים מקוננים

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

לדוגמא, נניח שיש לנו סוג מורכב מקונן כתובת בתוך ה עוֹבֵד מעמד:

ממשק ציבורי @FreeBuilder כתובת {String getCity (); Class Builder מרחיב את Address_Builder {}}

כעת, FreeBuilder מייצר מגדיר שיטות שננקטות כתובת. בונה כקלט יחד עם כתובת סוּג:

Address.Builder addressBuilder = Address.Builder חדש (); addressBuilder.setCity (CITY_NAME); עובד שכיר = builder.setName ("baeldung") .setAddress (addressBuilder) .build ();

יש לציין כי FreeBuilder גם מוסיף שיטה ל- התאמה אישית של הקיים כתובת חפץ ב עוֹבֵד:

עובד שכיר = builder.setName ("baeldung") .setAddress (addressBuilder) .mutateAddress (a -> a.setPinCode (112200)) .build ();

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

10. בניית אובייקט חלקי

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

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

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

עובד שכיר = builder.setName ("baeldung") .setAge (10) .setEmail ("[מוגן באמצעות הדוא"ל]") .buildPartial (); assertNotNull (employee.getEmail ());

לכן, למרות שלא הגדרנו את כל שדות החובה עוֹבֵד, עדיין נוכל לאמת שה- אימייל לשדה יש ​​ערך חוקי.

11. מותאם אישית toString () שיטה

עם אובייקטים ערכיים, לעתים קרובות אנו צריכים להוסיף מותאם אישית toString () יישום. FreeBuilder מאפשר זאת באמצעות תַקצִיר שיעורים:

@FreeBuilder מעמד מופשט ציבורי שכיר {מופשט מחרוזת getName (); מופשט int getAge (); @ עקוב ציבורי מחרוזת toString () {return getName () + "(" + getAge () + "בן שנים)"; } Builder Class Static ציבורי מרחיב את Employee_Builder {}}

הכרזנו עוֹבֵד כמעמד מופשט ולא ממשק וסיפק מנהג toString () יישום.

12. השוואה עם ספריות בונה אחרות

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

    • שיטות ממפה
    • סוגים מקוננים לבנייה
    • אובייקטים חלקיים

13. מסקנה

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

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

כל דוגמאות הקוד זמינות ב- GitHub.


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