Cách xử lý cờ trong nhiều if-other


10

Tôi dường như thấy điều này thường xuyên đủ trong mã của tôi và những người khác. Không có gì về nó có vẻ sai lầm khủng khiếp, nhưng nó làm tôi khó chịu vì có vẻ như nó có thể được thực hiện tốt hơn. Tôi cho rằng một tuyên bố trường hợp, có thể có ý nghĩa hơn một chút, nhưng thường thì biến là một loại không hoạt động tốt hoặc hoàn toàn với các báo cáo trường hợp (tùy thuộc vào ngôn ngữ)

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

Dường như có nhiều cách để "tính" yếu tố này, chẳng hạn như 2 bộ if-elses, trong đó một bộ xử lý khi Flag == true.

Có một "cách tốt" để tính đến yếu tố này, hoặc có lẽ khi thuật toán if-if này xảy ra, điều đó thường có nghĩa là bạn đang làm gì đó sai?


6
có thể chuyển biến Flag cho doFooX có thể tự xử lý cờ không?
Jean-François Côté

chắc chắn nhưng sau đó bạn chỉ có một phương thức doFooX, để đánh giá xem cờ có đúng không và doFooX1 hoặc doFooX2
TruthOf42

5
IMHO, nó vẫn sẽ rõ ràng hơn để đọc. Sau đó, nó phụ thuộc vào những gì doFooA và doFooA2 làm ...
Jean-François Côté

2
Tại sao viết if (Flag == true)chứ không chỉ If (Flag)? Nếu bạn nghĩ rằng If (Flag == true)tốt hơn, tại sao không if ((Flag == true) == true)?
Keith Thompson

1
Điều quan trọng nhất mang đi từ hầu hết các câu trả lời dưới đây là sự đơn giản và dễ đọc quan trọng hơn nhiều so với các thủ thuật thông minh khi nói về luồng logic và duy trì mã trong tương lai.
Patrick Hughes

Câu trả lời:


18

Nó có thể được xử lý với đa hình.

factory(var, flag).doFoo();

Bất cứ khi nào bạn có một loạt if / other kiểm tra loại của một cái gì đó, bạn có thể xem xét việc tập trung kiểm tra if / other trong một phương thức nhà máy, sau đó gọi doFoo () một cách đa hình. Nhưng điều này có thể là quá mức cho giải pháp 1 lần.

Có lẽ bạn có thể tạo bản đồ khóa / giá trị trong đó khóa là var / flag và giá trị là chính hàm đó.

do[var, flag]();

2
+1: Tra cứu bảng đánh bại các câu lệnh if lồng nhau gần như mọi lúc.
kevin cline

1
Tôi muốn nói đây là giải pháp tốt nhất.
Người đàn ông Muffin

6

Nhiều if lồng nhau làm tăng độ phức tạp chu kỳ của mã. Cho đến gần đây, việc có nhiều điểm thoát trong một hàm được coi là mã có cấu trúc xấu, nhưng bây giờ, miễn là mã đơn giản và ngắn , bạn có thể làm như vậy, làm cho mã trở nên tầm thường để đọc:

    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

tùy chọn khác là kết hợp nếu và chuyển đổi. Điều này không vượt trội so với kỹ thuật lồng nhau của bạn, nhưng có thể giảm số lần kiểm tra trùng lặp (nếu công tắc tối ưu hóa thành bảng nhảy).


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

Chà, luôn có điều này ...

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

Nhưng thành thật mà nói, tôi nghĩ rằng mã ban đầu không phải là một nửa xấu ở nơi đầu tiên.


0

Sử dụng đa hình và một rulemảng

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);
  }
}

Hoặc như được mike30đề xuất: Nếu các điều kiện quy tắc có thể dễ dàng tạo thành khóa thì hashmap là cách tốt nhất để đi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.