วิธีจัดการกับค่าสถานะใน if-else หลายรายการ


10

ฉันดูเหมือนจะเห็นสิ่งนี้บ่อยพอในรหัสของฉันและคนอื่น ๆ ดูเหมือนจะไม่มีอะไรผิดปกติ แต่มันทำให้ฉันรำคาญเพราะดูเหมือนว่ามันจะทำได้ดีกว่า ฉันคิดว่าคำสั่งกรณีอาจทำให้รู้สึกมากกว่าเล็กน้อย แต่บ่อยครั้งที่ตัวแปรเป็นประเภทที่ไม่ทำงานได้ดีหรือเลยด้วยคำสั่ง case (ขึ้นอยู่กับภาษา)

If variable == A
    if (Flag == true)
        doFooA()
    else
        doFooA2

else if variable == B
    if (Flag == true)
        doFooB()
    else
        doFooB2
else if variable == C
    if (Flag == true)
        doFooC()
    else
        doFooC2

ดูเหมือนว่ามีหลายวิธีในการ "คำนึงถึง" สิ่งนี้เช่น if-elses 2 ชุดโดยที่หนึ่งชุดจัดการเมื่อ Flag == จริง

มี "วิธีที่ดี" ในการคำนึงถึงปัจจัยนี้หรืออาจเกิดขึ้นเมื่ออัลกอริทึม if-else เกิดขึ้นมันมักจะหมายความว่าคุณกำลังทำอะไรผิดหรือเปล่า?


6
เป็นไปได้ไหมที่จะส่งตัวแปร Flag ไปยัง doFooX ที่สามารถจัดการกับตัวเองได้?
Jean-FrançoisCôté

แน่นอน แต่คุณมีเมธอด doFooX ซึ่งประเมินว่าการตั้งค่าสถานะเป็นจริงและจากนั้นทำ doFooX1 หรือ doFooX2 อย่างใดอย่างหนึ่ง
TruthOf42

5
IMHO มันจะยังคงชัดเจนในการอ่าน จากนั้นมันขึ้นอยู่กับว่า doFooA และ doFooA2 ทำอะไร ...
Jean-FrançoisCôté

2
ทำไมต้องเขียนif (Flag == true)มากกว่าแค่If (Flag)? หากคุณคิดว่าIf (Flag == true)ดีกว่าทำไมif ((Flag == true) == true)ล่ะ
Keith Thompson

1
สิ่งที่สำคัญที่สุดที่นำออกไปจากคำตอบส่วนใหญ่ด้านล่างคือความเรียบง่ายและการอ่านง่ายมีความสำคัญมากกว่าเทคนิคที่ชาญฉลาดเมื่อพูดถึงการไหลของตรรกะและการบำรุงรักษาโค้ดในอนาคต
Patrick Hughes

คำตอบ:


18

มันสามารถจัดการกับ polymorphism

factory(var, flag).doFoo();

เมื่อใดก็ตามที่คุณมี if / else ตรวจสอบชนิดของบางสิ่งคุณอาจพิจารณาการตรวจสอบ if / else แบบรวมศูนย์ในวิธีการของโรงงานจากนั้นเรียก doFoo () polymorphically แต่นี่อาจจะเป็นวิธีแก้ปัญหาแบบปิดเพียงครั้งเดียว

บางทีคุณสามารถสร้างแผนที่ / ค่าคีย์ที่สำคัญคือ var / flag และค่าเป็นฟังก์ชั่นของตัวเอง

do[var, flag]();

2
+1: การค้นหาตารางเอาชนะคำสั่ง if ที่ซ้อนกันเกือบทุกครั้ง
วินไคลน์

1
ฉันอยากจะบอกว่านี่เป็นทางออกที่ดีที่สุด
มัฟฟินแมน

6

ifs ที่ซ้อนกันหลายตัวเพิ่มความซับซ้อนของโค้ด จนถึงเมื่อเร็ว ๆ นี้การมีจุดออกหลายจุดในฟังก์ชั่นนั้นเป็นรหัสที่มีโครงสร้างที่ไม่ดี แต่ตอนนี้ตราบใดที่รหัสนั้นง่ายและสั้นคุณสามารถทำได้ทำให้โค้ดอ่านง่าย

    if (variable == A && Flag) {
        doFooA();
        return;
    }

    if (variable == A) {
        doFooA2();
        return;
    }

    if (variable == B && Flag){
        doFooB();
        return;
    }

    if (variable == B){
        doFooB2();
        return;
    }

    if (variable == C && Flag){
         doFooC();
         return;
    }

    if (variable == C){
         doFooC2();
    }

    return;

3

ตัวเลือกอื่นคือการรวมถ้าและสลับ สิ่งนี้ไม่ดีไปกว่าเทคนิคที่ซ้อนกันของคุณ แต่สามารถลดจำนวนการทดสอบซ้ำได้ (หากสวิตช์ปรับให้เหมาะสมกับตารางการกระโดด)


if (flag)
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
    }
}
else // flag == false
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
}

0

มันมีสิ่งนี้เสมอ ...

if variable == A && Flag
    doFooA()
else if variable == A 
    doFooA2    
else if variable == B && Flag
    doFooB()
else if variable == B
    doFooB2
else if variable == C && Flag
     doFooC()
else if variable == C
     doFooC2

แต่ตรงไปตรงมาฉันคิดว่ารหัสดั้งเดิมไม่ได้แย่ไปกว่าครึ่งแล้ว


0

ใช้ความหลากหลายและruleอาร์เรย์

interface IRule() {
  boolean applicable(args...);
  obj apply(args...);
}

static final Array<IRule> rules = [new MeaningfulNameRule1(), new MeaningfulNameRule2(), ...];

/* where */
class MeaningfulNameRuleX extends IRule{ /* */ }

/* In your method */

for (rule in rules) {
  if (rule.applicable(a,b,c)){
    return rule.apply(e,f,g);
  }
}

หรือตามที่mike30แนะนำ: หากเงื่อนไขของกฎสามารถสร้างคีย์ได้อย่างง่ายดาย hashmap เป็นวิธีที่ดีที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.