سؤال

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

وبعض أمثلة التعليمات البرمجية أدناه مبسطة.

ومتداخلة:

If(condition1)
{
    If(condition2)
    {
        if(condition3)
        {
            return true;
        }
        else
        {
            log("condition3 failed");
        }
    else
    {
        log("condition2 failed")
    }
}
else
{
    log("condition1 failed")
}

return false;

أو

ومنطقية مدفوعة:

bool bRC = false;

bRC = (condition1);
if(brc)
{
    bRC = (condition2);
}
else
{
    log("condition1 failed");
    return false;
}

if(bRC)
{
    bRC = (condition3);
}
else
{
    log("condition2 failed");
    return false;
}

if(bRC)
{
    return true;
}
else
{
    log("condition3 failed");
    return false;
}
هل كانت مفيدة؟

المحلول

وأنا أحب لك أفضل، ولكن ربما كنت تفعل شيئا مثل:

if (condition1 && condition2 && condition3)
{
    return true;
}
else if (!condition1)
{
    log("condition1 failed");
}
else if (!condition2)
{
    log("condition2 failed");
}
else
{
    log("condition3 failed");
}
return false;

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

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

نصائح أخرى

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

if(!condition1)
{
    log("condition1 failed");
    return false;
}

if(!condition2)
{
    log("condition2 failed");
    return false;
}

if(!condition3)
{
    log("condition3 failed");
    return false;
}

return true;

وربما هذا هو المساواة غير محسوب النفور إلى super-التعشيش، ولكن من المؤكد انها أنظف من حماقة له تخزين الشروط المنطقية في قيم معينة. ومع ذلك، قد تكون أقل قابلية للقراءة في السياق: النظر في ما إذا كان isreadable() أحد الشروط. انها أكثر وضوحا أن أقول if(isreadable()) لأننا نريد أن نعرف إذا كان هناك شيء غير قابل للقراءة. يشير if(!isreadable()) إذا كنا نريد أن نعرف ما اذا كان غير قابل للقراءة، وهي ليست لدينا النية. من المؤكد انها قابلة للنقاش والتي قد تكون هناك حالات حيث واحد هو أكثر قابلية للقراءة / بديهية من الآخر، ولكن أنا من محبي هذا الطريق نفسي. إذا كان يحصل علق شخص ما على العودة، ويمكن القيام بذلك:

if(!condition1)
    log("condition1 failed");

else if(!condition2)
    log("condition2 failed");

else if(!condition3)
    log("condition3 failed");

else
    return true;

return false;

ولكن هذا يخفى نوعا ما، وأقل "واضح" في رأيي.

وأنا شخصيا أجد رمز متداخلة أسهل بكثير للقراءة.

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

وعلى غرار النسخة متداخلة، ولكن أنظف بكثير بالنسبة لي:

if not condition1:
    log("condition 1 failed")
else if not condition2:
    log("condition 2 failed")
else if not condition3:
    log("condition 3 failed")
else
    return true;
return false;

وحذار أن كل حالة يتم تقييم مرة واحدة.

والنمط الثاني هو مطول سخيف: وقال انه اقترح حقا هذا بالضبط؟ لا تحتاج معظم تلك التصريحات if، لأن هناك return في جزء آخر.

ومع المثال متداخلة كنت تعتمد على عدم نسيان تتضمن أي بنود else الممكنة.

وأيا من هذه يبدو مرضيا بالنسبة لي.

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

وأعتقد أن كلا طرق ممكنة ولها إيجابيات وسلبيات. وأود أن استخدام أسلوب يحركها منطقي في الحالات التي كنت أود أن يكون تداخل عميق حقا (8 أو 10 أو شيء من هذا القبيل). في قضيتك مع 3 مستويات، وأود أن تختار طريقتك ولكن بالنسبة للعينة دقيقة من فوق، وأود أن تذهب من هذا القبيل:

void YourMethod(...)
{
  if (condition1 && condition2 && consition3)
    return true;

  if (!condition 1)
    log("condition 1 failed");

  if (!condition 2)
    log("condition 2 failed");

  if (!condition 3)
    log("condition 3 failed");

  return result;
}

... أو ما شابه ذلك إذا كنت تفضل نقطة الخروج واحدة (كما أفعل) ...

void YourMethod(...)
{
  bool result = false;

  if (condition1 && condition2 && consition3)
  { 
    result = true;
  }
  else
  {
    if (!condition 1)
      log("condition 1 failed");

    if (!condition 2)
      log("condition 2 failed");

    if (!condition 3)
      log("condition 3 failed");
  }
  return result;
}

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

وربما سأذهب مع

   if (!condition1)      log("condition 1 failed");
   else if (!condition2) log("condition 2 failed");
   else if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

والذي اعتقد انه نظافة equivilent والكثير ...

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

   if (!condition1) log("condition 1 failed");
   if (!condition2) log("condition 2 failed");
   if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

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

if (!condition1) {
    log("condition1 failed");
    return false;
}
if (!condition2) {
    log("condition2 failed");
    return false;
}
if (!condition3) {
    log("condition3 failed");
    return false;
}
return true;

ومع ذلك، أعتقد أنه من الأرجح أن كل حالة فشل يجب أن يتم تسجيل.

result = true;
if (!condition1) {
    log("condition1 failed");
    result = false;
}
if (!condition2) {
    log("condition2 failed");
    result = false;
}
if (!condition3) {
    log("condition3 failed");
    result = false;
}
return result;

وإذا كانت اللغة تدعم معالجة الاستثناء، كنت اذهب مع ما يلي:

try {
    if (!condition1) {
        throw "condition1 failed";
    }

    if (!condition2) {
        throw "condition2 failed";
    }

    if (!condition3) {
        throw "condition3 failed";
    }

    return true;

} catch (e) {
    log(e);
    return false;
}

وتحرير من تشارلز bretana: يرجى الاطلاع على استخدام الاستثناءات لتدفق السيطرة

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

ومثال ستكون مجموعة عقد الشروط، التي من خلالها سوف تكرار مع فترة من الوقت، وطباعة / استراحة حسب الحاجة.

وهناك الكثير من التطبيقات حسب احتياجاتك ذلك خلق رمز المثال سيكون من العبث.

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

ويجب إعادة التأكيد على مدونة مشكلة في لغة معينة. لذلك أرى أن أي قصاصات يمكن أن يكون "أفضل". ذلك يعتمد على غرار يجري المشكلة. على الرغم من أن تخميني هو أن أيا من الحلول وموازية المشكلة الفعلية. إذا وضعت بالقيمة الحقيقية بدلا من condition1،2،3 قد تغير تماما رمز "أفضل".
وأظن أن هناك (3D) أفضل طريقة لكتابة أن كل ذلك معا.

if( condition1 && condition2 && condition3 )
    return true;

log(String.Format("{0} failed", !condition1 ? "condition1" : (!condition2 ? "condition2" : "condition3")));
return false;

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

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