كيفية إزالة عبارات التصحيح من كود الإنتاج في جافا

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

سؤال

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

من السهل تعيين خاصية (debug = true) والتحقق منها في كل عبارة تصحيح، ولكن هذا يمكن أن يقلل الأداء.سيكون من الرائع أن يقوم المترجم ببساطة بإخفاء عبارات التصحيح.

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

المحلول

توصيتان.

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

وإذا كان لديك أكثر من بيان سجل واحد، فقم بحماية الكتلة بأكملها:

(log4j، على سبيل المثال :)

if (logger.isDebugEnabled()) {

  // perform expensive operations
  // build string to log

  logger.debug("....");
}

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

ثانية:

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

 assert (sky.state != FALLING) : "The sky is falling!";

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

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

نصائح أخرى

public abstract class Config
{
    public static final boolean ENABLELOGGING = true;
}

import static Config.*;

public class MyClass
{
    public myMethod()
    {
        System.out.println("Hello, non-logging world");

        if (ENABLELOGGING)
        {
            log("Hello, logging world.");
        }
    }
}

سيقوم برنامج التحويل البرمجي بإزالة كتلة الكود بـ "Hello ، World World." في ذلك إذا تم تعيين enable_logging على صحيح لأنه قيمة نهائية ثابتة.إذا كنت تستخدم أداة تشويش مثل proguard، فستختفي فئة Config أيضًا.

سيسمح التعتيم أيضًا بأشياء مثل هذه بدلاً من ذلك:

public class MyClass
{
    public myMethod()
    {
        System.out.println("Hello, non-logging world");

        Log.log("Hello, logging world.");
    }
}

import static Config.*;

public abstract class Log
{
    public static void log(String s)
    {
        if (ENABLELOGGING)
        {
            log(s);
        }
    }
}

سيتم تقليل الطريقة Log#log إلى لا شيء في المترجم، وستتم إزالتها بواسطة أداة التعتيم، بالإضافة إلى أي استدعاءات لهذه الطريقة، وفي النهاية ستتم إزالة فئة السجل نفسها.

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

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

يستخدم معالج جافا المسبق؟(google foo منخفض ولكن هذا رابط لمنتديات جويل القديمة التي تناقشه)

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

أود أيضًا أن أوصي بشدة باستخدام إطار عمل التسجيل.

ال logger.IsDebugEnabled() ليس إلزاميًا، كل ما في الأمر هو أنه يمكن أن يكون أسرع للتحقق مما إذا كان النظام في مستوى التصحيح قبل التسجيل.

إن استخدام إطار عمل التسجيل يعني أنه يمكنك تكوين مستويات التسجيل بسرعة دون إعادة تشغيل التطبيق.

يمكن أن يكون لديك تسجيل مثل:

logger.error("Something bad happened")
logger.debug("Something bad happend with loads more detail")

هذا "حيلة"يبدو أن عبارات تصحيح الأخطاء الخاصة بك قد اختفت

public static final boolean DEBUG = false;

if (DEBUG) { //disapeared on compilation }

ال بريد قال ذلك javac ذكي بما فيه الكفاية للتحقق من static final boolean واستبعاد عبارات التصحيح.(لم أجربه شخصيا)

بالنسبة للتسجيل، أنا شخصياً لا أحب رؤية الكود مثل:

if (logger.isDebugEnabled()) {
    logger.debug("....");
}
realImportantWork();

أشياء التسجيل تصرف انتباهي عن realImportantWork().الطريقة الصحيحة بالنسبة لي هي:

logger.debug("....");
realImportantWork()

بالإضافة إلى التكوين الذي يستثني جميع رسائل تصحيح الأخطاء في الإنتاج.

أعني أن logger.isDebugEnabled() يجب أن تكون السيطرة هي وظيفة إطار التسجيل، وليس وظيفتي.تدعم معظم مفاهيم إطار عمل التسجيل مثل "logger" و"LogLevel".والتي يمكن أن تفعل الخدعة.

للإجابة مباشرة على سؤالك:لا أعرف.

ولكن هنا حل آخر لمشكلتك:وفي رأيي هناك قولان يتعارضان هنا:"بيانات التصحيح" و"رمز الإنتاج".

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

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

ما لم يكن لدينا تعريف مختلف لرمز الإنتاج، فيجب عليك التفكير في إخراج عبارات التصحيح بعد اختبار الكود والانتهاء منه.

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