Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نمط Builder

جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 67 من 87.

نمط Builder هو نمط تصميم إنشائي يحل مشكلة شائعة: إنشاء كائنات معقدة تحتوي على العديد من المعلمات الاختيارية. بدلًا من إنشاء عدة مُنشئات أو تمرير null للمعلمات غير المستخدمة، يتيح لك Builder إنشاء الكائنات خطوةً بخطوة.

لنفترض إنشاء كائن User مع fields مطلوبة (name، email) وأخرى اختيارية (age، phone، address). من دون Builder، ستحتاج إلى مُنشئات متداخلة أو مُنشئ فوضوي ذي العديد من parameter. يقدّم نمط 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);
        }
    }
}

تُرجع methods الخاصة بـ Builder القيمة this، مما يتيح method التسلسل: طريقة سلسة وسهلة القراءة لإنشاء الكائنات:

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

لاحظ أن مُنشئ User خاص: لا يمكن إنشاء الكائنات إلا من خلال Builder. يتألق هذا النمط عندما تحتوي الكائنات على العديد من الحقول الاختيارية، مما يجعل شيفرتك أكثر قابلية للقراءة وأقل عرضة للأخطاء مقارنةً بقوائم المعلمات الطويلة.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا لطلب البيتزا باستخدام نمط Builder! بدلًا من التعامل مع constructor يأخذ عشرات parameter لجميع الإضافات والخيارات الممكنة، ستنشئ أداة إنشاء سلسة تجعل تخصيص البيتزا واضحًا وسهل القراءة.

ستنظّم التعليمات البرمجية عبر ملفين:

  • Pizza.java: أنشئ Pizza class يستخدم نمط Builder في الإنشاء. يجب أن تحتوي البيتزا على fields التالية:

    size (String) - مطلوب، ويمثل حجم البيتزا

    cheese (boolean) - اختياري، وقيمته الافتراضية هي false

    pepperoni (boolean) - اختياري، وقيمته الافتراضية هي false

    mushrooms (boolean) - اختياري، وقيمته الافتراضية هي false

    يجب أن يكون Pizza constructor خاصًا وأن يقبل PizzaBuilder فقط باعتباره parameter، مع نسخ جميع القيم من أداة الإنشاء إلى fields الخاصة بالبيتزا.

    ضمّن getDescription() method يعيد سلسلة نصية بهذا التنسيق: [size] Pizza with: [toppings] حيث تكون toppings قائمة مفصولة بفواصل للإضافات التي قيمتها true (Cheese, Pepperoni, Mushrooms). إذا لم يتم اختيار أي إضافات، فيجب أن يكون جزء الإضافات ببساطة no toppings.

    أنشئ class داخلية ثابتة باسم PizzaBuilder تتضمن:

    • constructor يأخذ size parameter المطلوب
    • methods باسم cheese() وpepperoni() وmushrooms()، يعيّن كل منها القيمة المنطقية الخاصة بها إلى true ويعيد this للسماح بالتسلسل
    • build() method يعيد Pizza جديدة
  • Main.java: أظهر أداة إنشاء البيتزا أثناء عملها! ستتلقى أربعة مدخلات: حجم البيتزا (String)، وثلاث قيم yes/no (Strings) تشير إلى ما إذا كان ينبغي إضافة cheese وpepperoni وmushrooms على التوالي.

    أنشئ PizzaBuilder باستخدام الحجم المُعطى. ثم، استنادًا إلى كل مدخلة yes/no، قم بتسلسل methods الخاصة بالإضافة المناسبة. إذا كانت المدخلة هي "yes"، فاستدعِ method الخاصة بتلك الإضافة؛ وإذا كانت "no"، فتجاوزها. أخيرًا، استدعِ build() لإنشاء البيتزا.

    اطبع نتيجة استدعاء getDescription() على البيتزا المكتملة.

ستتلقى أربع مدخلات بالترتيب: size (String)، وadd cheese (String: "yes" أو "no")، وadd pepperoni (String: "yes" أو "no")، وadd mushrooms (String: "yes" أو "no").

على سبيل المثال، عند استخدام المدخلات Large وyes وno وyes، سيكون الناتج: Large Pizza with: Cheese, Mushrooms

لاحظ كيف يتيح لك نمط Builder إنشاء بيتزا بأي مجموعة من الإضافات دون الحاجة إلى constructors منفصلة لكل احتمال!

جرّب بنفسك

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 عبر الإنترنت