سؤال

أنا أتساءل لماذا assert الكلمة الأساسية غير مستخدمة بشكل كافٍ في Java؟لم يسبق لي أن رأيتهم مستخدمين تقريبًا، لكنني أعتقد أنها فكرة رائعة.أنا بالتأكيد أفضل الاختصار:

assert param != null : "Param cannot be null";

إلى لفظ:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}

شكوكي هي أنهم غير مستغلين بشكل كافٍ بسبب

  • لقد وصلوا متأخرين نسبيًا (Java 1.4)، وفي ذلك الوقت كان العديد من الأشخاص قد أسسوا بالفعل أسلوب/عادات برمجة Java الخاصة بهم
  • يتم إيقاف تشغيلها في وقت التشغيل بشكل افتراضي
هل كانت مفيدة؟

المحلول

التأكيدات هي، من الناحية النظرية، للاختبار الثوابت, ، افتراضات ذلك يجب يكون صحيحًا حتى يكتمل الرمز بشكل صحيح.

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

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

إن وجهة نظرك حول قدومهم "متأخرًا" إلى Java هي أيضًا سبب لعدم رؤيتهم على نطاق أوسع.

أيضًا، تسمح أطر اختبار الوحدة بأن تكون بعض الحاجة إلى التأكيدات البرمجية خارجة عن الكود الذي يتم اختباره.

نصائح أخرى

من إساءة استخدام التأكيدات استخدامها لاختبار إدخال المستخدم.رمي ان IllegalArgumentException على إدخال غير صالح هو الأصح، لأنه يسمح لأسلوب الاستدعاء بالتقاط الاستثناء وعرض الخطأ والقيام بكل ما يلزم (اطلب الإدخال مرة أخرى، إنهاء، أي شيء).

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

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

من البرمجة مع التأكيدات

افتراضيًا، يتم تعطيل التأكيدات في وقت التشغيل.يسمح لك مفتاحا تبديل سطر الأوامر بتمكين التأكيدات أو تعطيلها بشكل انتقائي.

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

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

yc

@دون، أنت تشعر بالإحباط بسبب إيقاف تشغيل التأكيد افتراضيًا.لقد كنت كذلك، وبالتالي كتبت هذا البرنامج الإضافي الصغير javac الذي يقوم بتضمينهم (أي يصدر الرمز الثانوي لـ if (!expr) throw Ex بدلاً من هذا الرمز الثانوي السخيف للتأكيد.

إذا قمت بتضمين fa.jar في مسار الفصل الخاص بك أثناء تجميع تعليمات Java البرمجية، فإنه سيعمل بسحره ثم يخبرك بذلك

Note: %n assertions inlined.

@يرى http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions وبدلاً من ذلك على جيثب https://github.com/akuhn/javac

لست متأكدًا من سبب اهتمامك بكتابة التأكيدات ثم استبدالها بمعيار إذا كان بيان الشرط، فلماذا لا تكتب الشروط كما لو في المقام الأول؟

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

لا ينبغي استخدام التأكيدات للتحقق من صحة الشروط لأن ذلك يعني أن سلوك تطبيقك يختلف في وقت التشغيل عندما يتم تمكين/تعطيل التأكيدات - وهو كابوس!

التأكيدات مفيدة لأنها:

  • اكتشف أخطاء البرمجة مبكرًا
  • رمز المستند باستخدام الرمز

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

في المبرمج العملي حتى أنهم يوصون بالسماح لهم بالعمل في الإنتاج.

ترك التأكيدات قيد التشغيل

استخدم التأكيدات لمنع المستحيل.

لاحظ أن التأكيدات ترمي AssertionError إذا فشلت، لذلك لا يتم اكتشافها عن طريق صيد الاستثناء.

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

أيضًا، لا يمكنك البحث عن التأكيدات في أي بيئة تطوير متكاملة (IDE) رأيتها حتى الآن ولكن يمكن لكل بيئة تطوير متكاملة (IDE) البحث عن استدعاءات الطريقة.

في الواقع وصلوا إلى Java 1.4

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

وكما ذكر آخرون:التأكيدات ليست مناسبة للتحقق من صحة إدخال المستخدم.

إذا كنت مهتمًا بالإسهاب، أنصحك بمراجعة المكتبة التي كتبت فيها: https://bitbucket.org/cowwoc/requirements/.سيسمح لك بالتعبير عن عمليات التحقق هذه باستخدام القليل جدًا من التعليمات البرمجية، وسيقوم أيضًا بإنشاء رسالة الخطأ نيابةً عنك:

requireThat("name", value).isNotNull();

وإذا أصررت على استخدام التأكيدات، فيمكنك القيام بذلك أيضًا:

assertThat("name", value).isNotNull();

سيبدو الإخراج كما يلي:

java.lang.NullPointerException: name may not be null

ليرة تركية ؛ د

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

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

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

تطبيقات الإنتاجية

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

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

تطبيقات الأعمال

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

اختبار قواعد العمل

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

ظروف وقت التشغيل

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

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

الشيكات الصحية

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

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

(بالمناسبة، يجب أن أذكر... لا تستخدم أبدًا النقطة العائمة مقابل المال, ، يستخدم BigDecimal.)

اختيار الأطر

بدلا من استخدام المدمج في assert منشأة، قد ترغب في النظر في استخدام إطار تأكيد آخر.أمامك خيارات متعددة، منها:

أو لفة بنفسك.قم بإنشاء فصل صغير لاستخدامه في مشروعك.شيء من هذا القبيل.

package work.basil.example;

public class Assertions {
    static public void assertTrue ( Boolean booleanExpression , CharSequence message ) throws java.lang.AssertionError {
        if ( booleanExpression ) {
            // No code needed here.
        } else { // If booleanExpression is false rather than expected true, throw assertion error.
            // FIXME: Add logging.
            throw new java.lang.AssertionError( message.toString() );
        }
    }

}

مثال على الاستخدام:

Assertions.assertTrue( 
    localTime.isBefore( LocalTime.NOON ) , 
    "The time-of-day is too late, after noon: " + localTime + ". Message # 816a2a26-2b95-45fa-9b0a-5d10884d819d." 
) ;

أسئلتك

لقد وصلوا متأخرين نسبيًا (Java 1.4)، وفي ذلك الوقت كان العديد من الأشخاص قد أسسوا بالفعل أسلوب/عادات برمجة Java الخاصة بهم

نعم، هذا صحيح تماما.أصيب العديد من الأشخاص بخيبة أمل بسبب واجهة برمجة التطبيقات (API) التي طورتها Sun/JCP لاختبار التأكيد.كان تصميمه باهتًا مقارنة بالمكتبات الموجودة.لقد تجاهل الكثيرون واجهة برمجة التطبيقات الجديدة، وتمسكوا بالأدوات المعروفة (أدوات الطرف الثالث، أو المكتبة الصغيرة الخاصة بك).

يتم إيقاف تشغيلها في وقت التشغيل افتراضيًا، لماذا أوه لماذا؟؟

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

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

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