منشئ مع جميع خصائص الفئة أو منشئ افتراضي مع المستوطنين؟

StackOverflow https://stackoverflow.com/questions/830657

  •  06-07-2019
  •  | 
  •  

سؤال

وفيما يلي النهجين:

  • منشئ مع كافة خصائص الطبقة

الايجابيات:يجب أن أضع عددًا محددًا من أنواع المعلمات، لذا إذا ارتكبت خطأً، يحذرني المترجم (بالمناسبة، هل هناك طريقة لمنع مشكلة تبديل عددين صحيحين في قائمة المعلمات عن طريق الخطأ؟)

سلبيات:إذا كان لدي الكثير من الخصائص، فيمكن أن يصبح خط إنشاء مثيل طويل جدًا ويمكن أن يمتد على سطرين أو أكثر

  • المستوطنون والمنشئ الفارغ الافتراضي

الايجابيات:أستطيع أن أرى بوضوح ما أقوم بإعداده، لذا إذا كنت أفعل شيئًا خاطئًا، فيمكنني تحديده بمجرد كتابته (لا يمكنني ارتكاب الخطأ السابق المتمثل في تبديل متغيرين من نفس النوع)

سلبيات:قد يستغرق إنشاء كائن يحتوي على الكثير من الخصائص عدة أسطر (لا أعرف ما إذا كان هذا خدعة حقًا) وإذا نسيت تعيين خاصية، فلن يقول المترجم أي شيء.

ماذا ستفعل ولماذا؟هل تعرف أي نمط ضوئي (ضع في اعتبارك أنه يجب استخدامه في كل مرة يتم فيها إنشاء كائن يحتوي على 7+ خصائص) لاقتراحه؟أنا أسأل هذا لأنني أميل إلى كره المنشئات الكبيرة حيث لا أستطيع أن أعرف بسرعة أين يوجد المتغير الذي أبحث عنه، ومن ناحية أخرى أجد "تعيين جميع الخصائص" عرضة لفقدان بعض الخصائص.

لا تتردد في مناقشة افتراضاتي في إيجابيات وسلبيات لأنها مجرد أفكاري :)

تحديث - سؤال وجدته يتعلق بهذا: بناء كائنات كبيرة وغير قابلة للتغيير دون استخدام المُنشئات التي تحتوي على قوائم طويلة من المعلمات

هل كانت مفيدة؟

المحلول

يمكنك إلقاء نظرة على نمط البناء الذي دعا إليه جوشوا بلوخ، ووصفه في جافا فعالة.هناك عرض تقديمي مع النقاط الرئيسية في http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2689.pdf;لا شك أنه يمكنك البحث عن مرجع أفضل.

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

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

Message message = new Message.Builder()
    .sender( new User( ... ) )
    .recipient( new User( ... ) )
    .subject( "Hello, world!" )
    .text( messageText )
    .build();

جزء من Message.Builder قد تبدو مشابهة لما يلي:

public class Builder {

    private User sender = null;
    // Other properties

    public Builder sender( User sender ) {
        this.sender = sender;
        return this;
    }
    // Methods for other properties

    public Message build() {
        Message message = new Message();
        message.setSender( sender );
        // Set the other properties
        return message;
    }

}

نصائح أخرى

لقد فاتتك أكبر ميزة تتمثل في وجود مُنشئ يحتوي على الكثير من المعلمات:يتيح لك إنشاء أنواع غير قابلة للتغيير.

الطريقة العادية لإنشاء أنواع غير قابلة للتغيير بدون قبح المنشئ الضخم هو أن يكون لديك نوع مساعد - أ منشئ الذي يحافظ على القيم التي تريدها في كائنك النهائي، ثم يبني الكائن غير القابل للتغيير عندما تكون جاهزًا.

تشير الأبحاث الأكاديمية الحديثة (CMU وMicrosoft) حول قابلية استخدام واجهة برمجة التطبيقات (API) إلى أن المنشئات الافتراضية مع أدوات الضبط ستكون هي الطريقة التي يجب اتباعها من حيث سهولة الاستخدام.هذا من "الآثار المترتبة على قابلية الاستخدام للمعلمات المطلوبة في منشئي الكائنات" بقلم جيف ستايلوس وستيفن كلارك وتم تقديمه في المؤتمر الدولي لهندسة البرمجيات:

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

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

يعد تصحيح أخطاء Getters وSetters أسهل إلى حد كبير، خاصة إذا قمت بإنشاء ضمانات تؤدي إلى استثناء وقت التشغيل إذا لم يتم ملء الكائن بشكل صحيح.وأنا من أشد المعجبين بـ "سهل التصحيح".

قبل هذا الموضوع، لم أسمع مطلقًا عن نموذج البناء الذي ذكره روب.لم أستخدمها بنفسي أبدًا (من الواضح)، لكنها مثيرة للاهتمام للغاية.

أفضّل أخذ حجج المُنشئ، لأسباب الثبات المذكورة أعلاه.إذا كان هذا يمنحك مُنشئًا يتطلب الكثير من الوسيطات (على سبيل المثال أكثر من أربعة أو نحو ذلك)، فهذه رائحة رمزية بالنسبة لي:يجب تجميع بعض هذه الوسائط معًا في أنواع خاصة بها.

على سبيل المثال، إذا كان لديك شيء مثل هذا:

class Contact
{
    public Contact(string firstName, string lastName, string phoneNumber,
        string street, string city, string state, int zipCode) { ... }
}

سأعيد تشكيلها إلى:

class Contact
{
    public Contact(Person person, PhoneNumber number, Address address) { ... }
}

class Person
{
    public Person(string firstName, string lastName) { ... }
}

class PhoneNumber
{
    public PhoneNumber(string digits) { ... }
}

class Address
{
    public Address(string street, string city, string state, int zipCode) { ... }
}

تعد الفصول الكبيرة جدًا مشكلة تصميم شائعة جدًا في قواعد تعليمات OOP.

هناك جوانب أخرى كذلك.إذا كنت تريد أن تكون قادرًا على القيام بأشياء معينة مع فصلك في وقت التصميم بدلاً من وقت التشغيل فقط، على سبيل المثال إضافة فصلك ككائن في لوحة الكائنات (هذا هو Java باستخدام Netbeans)، فأنت بحاجة إلى توفير مُنشئ بدون وسيطات في حتى تتمكن من القيام بذلك.

هناك استراتيجيات أخرى هنا أيضًا.قبل محاولة معرفة كيفية التعامل مع الكثير من المعلمات، أعتقد أنه من المهم إعادة النظر في التصميم الخاص بك والنظر في ما إذا كان فصلك يفعل الكثير.معرفة ما إذا كان بإمكانك تجميع بعض المعلمات معًا في فئة جديدة، ونقل بعض السلوك إلى تلك الفئة.

المستوطنون والمنشئ الفارغ الافتراضي

تطرق إليها JRL بشكل غير مباشر, ، ولكن أحد الأسباب التي تدفعك إلى التفكير في استخدام أدوات الضبط هو أن يكون الكائن متوافقًا مع مواصفات جافا بين.وهذا يجعل الحالات قابلة ل التحرير عبر أدوات الاستبطان والمثابرة باستخدام معين تقنيات التسلسل.

من يقول أنك لا تستطيع أن تفعل كلا الأمرين؟أود أن أقول أن الخصائص الإلزامية تدخل في المنشئ، ويتم التعامل مع الخصائص الاختيارية باستخدام أدوات الضبط.راجع للشغل، من يقول أنك تحتاج دائمًا إلى أداة ضبط واحدة لكل عقار؟إذا كانت خاصيتان تنتميان معًا من الناحية المفاهيمية، فلماذا لا نجمعهما معًا؟

أنا أحب نمط البناء أيضًا، لكن القاعدة الأكثر أهمية هي:استخدم عقلك دائمًا وابحث عن التصميم الذي يناسب المشكلة المحددة.لا يوجد حل واحد يناسب الجميع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top