Menu
Coddy logo textTech

תבנית Builder

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 67 מתוך 87.

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

שקלו ליצור אובייקט User עם שדות חובה (שם, דוא״ל) ושדות אופציונליים (גיל, טלפון, כתובת). בלי Builder, תצטרכו להשתמש בבנאים מדורגים או בבנאי מסורבל עם פרמטרים רבים. תבנית Builder מציעה גישה נקייה יותר:

public class User {
    private final String name;    // חובה
    private final String email;   // חובה
    private final int age;        // לא חובה
    private final String phone;   // לא חובה
    
    private User(UserBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.phone = builder.phone;
    }
    
    public static class UserBuilder {
        private final String name;
        private final String email;
        private int age;
        private String phone;
        
        public UserBuilder(String name, String email) {
            this.name = name;
            this.email = email;
        }
        
        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }
        
        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }
        
        public User build() {
            return new User(this);
        }
    }
}

השיטות של הבנאי מחזירות את this, וכך מאפשרות שרשור שיטות: דרך זורמת וקריאה לבניית אובייקטים:

User user = new User.UserBuilder("Alice", "alice@email.com")
    .age(25)
    .phone("555-1234")
    .build();

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

challenge icon

אתגר

קל

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

תארגנו את הקוד שלכם בשני קבצים:

  • Pizza.java: צרו מחלקה Pizza שמשתמשת בתבנית Builder ליצירת אובייקטים. לפיצה שלכם צריכים להיות השדות הבאים:

    size (String) - חובה, מייצג את גודל הפיצה

    cheese (boolean) - אופציונלי, ברירת המחדל היא false

    pepperoni (boolean) - אופציונלי, ברירת המחדל היא false

    mushrooms (boolean) - אופציונלי, ברירת המחדל היא false

    הבנאי של Pizza צריך להיות private ולקבל רק PizzaBuilder כפרמטר, ולהעתיק את כל הערכים מה-builder לשדות של הפיצה.

    כללו מתודה getDescription() שמחזירה מחרוזת בפורמט הזה: [size] Pizza with: [toppings], כאשר התוספות הן רשימה מופרדת בפסיקים של התוספות שערכן true (Cheese, Pepperoni, Mushrooms). אם לא נבחרו תוספות, החלק של התוספות צריך להכיל רק את no toppings.

    צרו מחלקה פנימית סטטית PizzaBuilder עם:

    • בנאי שמקבל את הפרמטר הנדרש size
    • מתודות cheese(), pepperoni() ו-mushrooms(), שכל אחת מהן מגדירה את הערך הבוליאני המתאים ל-true ומחזירה את this כדי לאפשר שרשור
    • מתודה build() שמחזירה Pizza חדשה
  • Main.java: הדגימו את פעולת ה-builder של הפיצה שלכם! תקבלו ארבעה קלטים: גודל הפיצה (String) ושלושה ערכי כן/לא (Strings) המציינים אם להוסיף גבינה, פפרוני ופטריות, בהתאמה.

    צרו PizzaBuilder עם הגודל הנתון. לאחר מכן, בהתאם לכל קלט כן/לא, שרשרו את המתודות המתאימות להוספת התוספות. אם הקלט הוא "yes", קראו למתודה של אותה תוספת; אם הוא "no", דלגו עליה. לבסוף, קראו ל-build() כדי ליצור את הפיצה.

    הדפיסו את התוצאה של קריאה ל-getDescription() על הפיצה שיצרתם.

תקבלו ארבעה קלטים לפי הסדר הבא: גודל (String), הוספת גבינה (String: "yes" או "no"), הוספת פפרוני (String: "yes" או "no"), הוספת פטריות (String: "yes" או "no").

לדוגמה, עבור הקלטים Large, yes, no, yes, הפלט שלכם יהיה: Large Pizza with: Cheese, Mushrooms

שימו לב כיצד תבנית Builder מאפשרת לכם ליצור פיצות עם כל שילוב של תוספות, בלי צורך בבנאים נפרדים לכל אפשרות!

נסו בעצמכם

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // קרא את הקלטים
        String size = scanner.nextLine();
        String addCheese = scanner.nextLine();
        String addPepperoni = scanner.nextLine();
        String addMushrooms = scanner.nextLine();
        
        // TODO: צור PizzaBuilder בגודל הנתון
        // TODO: שרשר את המתודות להוספת תוספות בהתאם לקלטים של yes/no
        // TODO: בנה את הפיצה והדפס את התיאור שלה
        
    }
}
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Java אונליין