2012-11-08 39 views
6

Câu lệnh báo cáo chuyển đổi là tốt để thay thế lồng nhau nếu câu lệnh nếu chúng ta có cùng điều kiện nhưng tiêu chí khác nhau. Nhưng cách tiếp cận tốt là gì nếu những câu lệnh lồng nhau nếu tất cả có điều kiện khác biệt và độc đáo? Tôi có bất kỳ lựa chọn thay thế nào để thay thế một tá câu lệnh khác nếu lồng vào nhau không?Thay thế Nếu Khác câu lệnh lồng nhau có điều kiện duy nhất

Sample Code:

  • Lưu ý: Tôi biết điều này là cực kỳ không đọc được - đó là toàn bộ vấn đề.
  • Lưu ý: Tất cả các điều kiện là duy nhất.

...

if (condition) { 
    // do A 
} else {      
    if (condition) { 
     // do B 
    if (condition) { 
     if (condition) { 
      if (condition) { 
       // do C 
       if (condition) { 
        // do D 
        if (condition) { 
         // do E 
        } else {             
         if (condition) { 
          // do F 
         } 
        } 
       } 
      } 

      if (condition) { 
       // do G 
       if (condition) { 
        // do H 
        if (condition) { 
         // do I 
        } else { 
         // do J 
        } 
       } 
      } 
     } 
    } 
} 

+7

Nếu bạn ở trong tình huống này, rất có thể thiết kế của bạn vô cùng thiếu sót. –

+1

Như jordan kaye nói + NẾU bạn thực sự có điều kiện phức tạp như vậy, nếu người nào khác sẽ là cách dễ nhất để làm như vậy –

+0

Tôi đồng ý với ông Kaye. Có một vài câu trả lời đúng cho điều này tùy thuộc vào điều kiện là gì, đây không phải là một trong số họ. Đó là một liên hoan lỗi, hãy thử viết một bài kiểm tra đơn vị cho nó, nó có thể gợi ý một vài điều. –

Trả lời

1

Tôi phải kiểm tra đây là Stackoverflow không phải DailyWTF khi tôi thấy mã !!

Giải pháp là thay đổi kiến ​​trúc và sử dụng giao diện và đa hình để có được tất cả các điều kiện. Tuy nhiên rằng có lẽ một công việc rất lớn và ra khỏi phạm vi của một câu trả lời có thể chấp nhận, vì vậy tôi sẽ giới thiệu một cách khác để bạn kinda có thể sử dụng báo cáo Chuyển với điều kiện duy nhất:

[Flags] 
public enum FilterFlagEnum 
{ 
    None = 0, 
    Condition1 = 1, 
    Condition2 = 2, 
    Condition3 = 4, 
    Condition4 = 8, 
    Condition5 = 16, 
    Condition6 = 32, 
    Condition7 = 64 
}; 


public void foo(FilterFlagEnum filterFlags = 0) 
{ 
     if ((filterFlags & FilterFlagEnum.Condition1) == FilterFlagEnum.Condition1) 
     { 
      //do this 
     } 
     if ((filterFlags & FilterFlagEnum.Condition2) == FilterFlagEnum.Condition2) 
     { 
      //do this 
     } 
} 


foo(FilterFlagEnum.Condition1 | FilterFlagEnum.Condition2); 
3

Cách tiếp cận tốt nhất trong trường hợp này là để chop lên điều vào phương pháp riêng biệt có tên thích hợp.

+1

Tốt nhất? Tại sao không phải là một công cụ quy tắc? –

+1

Cũng giống như vậy. Nó chỉ trông khác. – Tar

1

Theo quan điểm của tôi, có hai phương pháp chính để loại bỏ các điều kiện lồng nhau. Người đầu tiên được sử dụng trong trường hợp đặc biệt hơn khi chúng ta chỉ có một điều kiện trong từng điều kiện lồng nhau như ở đây:

function A(){ 
    if (condition1){ 
     if (condition2){ 
      if (condition3){ 
       // do something 
      } 
     } 
    } 
} 

chúng tôi chỉ có thể đi ra khỏi tình trạng ngược lại với lợi nhuận:

function A(){ 
    if (condition1 == false) return; 
    if (condition2 == false) return; 
    if (condition3 == false) return; 
    // do something 
} 

Thứ hai một là sử dụng một phân hủy điều kiện và có thể được coi là phổ biến hơn so với cái đầu tiên. Trong trường hợp khi chúng ta có một cấu trúc điều kiện như thế này, ví dụ:

if (condition1) 
{ 
    // do this 1 
} 
else 
{             
    if (condition2) 
    { 
     // do this 2 
    }              
} 

Chúng ta có thể thực hiện một biến đối với từng điều kiện cụ thể như ở đây:

bool Cond1 = condition1; 
bool Cond2 = !condition1 && condition2; 

if (Cond1) { //do this 1 } 
if (Cond2) { //do this 2 } 
+1

Nhưng làm thế nào để đối phó với việc này? – Paparazzi

+0

Có, tôi đồng ý rằng điều này chỉ hoạt động đối với một số trường hợp đặc biệt như trong ví dụ của tôi về những điều kiện không có "khác". Nếu điều kiện lồng nhau và không có khác hơn chúng ta có thể loại bỏ rất nhiều cành lồng nhau. – apros

0

Nếu đó thực sự là logic kinh doanh thì cú pháp là OK. Nhưng tôi chưa bao giờ thấy logic kinh doanh phức tạp. Vẽ lên một biểu đồ dòng chảy và xem nếu nó không thể được đơn giản hóa.

if (condition) 
{ 
    // do this 
} 
else 
{             
    if (condition) 
    { 
     // do this 
    }              
} 

có thể được thay thế bằng

if (condition) 
{ 
    // do this 
} 
else if (condition) 
{ 
    // do this              
} 

Nhưng một lần nữa lùi lại và xem xét các thiết kế. Cần nhiều hơn một người khác nếu dọn dẹp.

+0

Điều cá nhân nhưng tôi chưa bao giờ thích điều đó, tôi luôn nhận được sự thôi thúc không thể kiểm soát để thêm nhiều dấu ngoặc và những thứ thụt vào. :) –

1

@Tar đề xuất một cách để xem xét nó. Khác có thể là.

Đảo ngược.

if (myObject.HasThing1) 
{ 
    if(myObject.HasThing2) 
    { 
     DoThing1(); 
    } 
    else 
    { 
     DoThing2(); 
    } 
} 
else 
{ 
    DoThing3(); 
} 

có thể

DoThing1(myObject.HasThing1); 
DoThing2(myObject.HasThing2); 
DoThing3(myObject.HasThing3); 

Vì vậy, mỗi Do phương pháp làm cho số lượng tối thiểu của các bài kiểm tra, nếu có thất bại của nó không có gì.

Bạn có thể làm cho nó thông minh hơn một chút nếu bạn muốn thoát khỏi chuỗi theo một vài cách.

Không biết liệu nó có hiệu quả với bạn hay không, nhưng việc ủy ​​quyền kiểm tra các điều kiện thường là đủ để xem xét mọi thứ, rằng một số yếu tố đơn giản có thể xuất hiện như thể bằng phép thuật.

0

Tôi cảm thấy nỗi đau của bạn.

Tình huống của tôi yêu cầu viết nhiều (> 2000) kiểm tra chức năng đã được khách hàng chỉ định cho một thiết bị lớn, đắt tiền. Trong khi hầu hết (> 95%) các xét nghiệm này rất đơn giản và có hàng chục lượt kiểm tra vượt qua/thất bại thẳng tiến vào "nhiều lồng nhau nếu điều này làm điều khác làm điều gì đó khác" ở độ sâu tương tự hoặc tệ hơn của bạn.

Giải pháp mà tôi đưa ra là lưu trữ Windows Workflow trong ứng dụng thử nghiệm của mình.

Tất cả các thử nghiệm phức tạp đã trở thành Quy trình làm việc mà tôi chạy với kết quả được báo cáo lại cho ứng dụng thử nghiệm của mình.

Khách hàng là hạnh phúc vì họ có khả năng:

  1. Xác logic test (khó khăn cho các lập trình viên không nhìn vào lồng sâu if/else C# - dễ dàng nhìn vào một sơ đồ đồ họa)
  2. Sửa kiểm tra đồ họa
  3. Thêm xét nghiệm mới

Hosting Windows Workflow (trong .NET 4/4.5) là rất dễ dàng - mặc dù nó có thể đưa bạn một thời gian để có được đầu của bạn xung quanh "liên lạc" được Tween các quy trình công việc và mã của bạn - chủ yếu là vì có nhiều cách để làm điều đó.

Chúc may mắn

Các vấn đề liên quan