2013-03-14 10 views
5

Mój program czeka na wprowadzenie danych przez użytkownika, a w razie potrzeby go przetworzy. Muszę sprawdzić dane wprowadzone przez użytkownika, aby upewnić się, że spełnia ono określone kryteria, a jeśli nie spełnia wszystkich tych kryteriów, zostanie ono odrzucone.Sprawdź, czy wprowadzone przez użytkownika błędy nie są eleganckie.

Pseudo-kod jest coś takiego:

if (fulfills_condition_1) 
{ 
    if (fulfills_condition_2) 
    { 
     if (fulfills_condition_3) 
     { 
      /*process message*/ 
     } 
     else 
      cout << error_message_3; //where error_message_1 is a string detailing error 
    } 
    else 
     cout << error_message_2; //where error_message_2 is a string detailing error 
} 
else 
    cout << error_message_1; //where error_message_3 is a string detailing error 

Istnieje możliwość, że niektóre z tych warunków może wzrosnąć, a ja zastanawiałem się, czy nie było schludniejszy drogę do reprezentowania pomocą przełącznika lub coś podobnego to zamiast wielu kaskadowych instrukcji if.

Wiem, że istnieje możliwość korzystania

if (fulfills_condition_1 && fulfills_condition_2 && fulfills_condition_3) 
    /*process message*/ 
else 
    error_message; //"this message is not formatted properly" 

ale jest to mniej użyteczny niż pierwszy, i nie powiedzieć, gdzie jest problem.

warunki można z grubsza ułożone w coraz większe znaczenie tj sprawdzanie condition_1 jest ważniejsze niż sprawdzanie condition_3, więc sprawozdania if zrobić pracę - ale czy jest lepszy sposób w ogóle to robisz?

+1

Wyjątki ..... –

+0

Czy rozważyłeś kontrole negatywnego stanu za pomocą klasy try-catch i klasy wyjątków, która dokładnie odzwierciedla stan, który spowodował problem w pierwszej kolejności? – WhozCraig

+0

To zależy od złożoności danych wejściowych. Utworzyłem DSL, aby zadeklarować, w jaki sposób dane wejściowe są poprawne, i utworzyć obiekty reprezentujące to DSL, a następnie powiedzieć, aby potwierdzić to wejście. –

Odpowiedz

2

Jak o

if (!fulfills_condition_1) throw BadInput(error_message_1); 
if (!fulfills_condition_2) throw BadInput(error_message_2); 
if (!fulfills_condition_3) throw BadInput(error_message_3); 

/* process message */ 

Wtedy twój obsługi wyjątku może zgłosić się komunikat o błędzie, a następnie ponów próbę lub przerwać jako właściwe.

1

Proponuję można użyć „szybkiego powrotu” technika:

if (!fulfills_condition_1) 
    // error msg here. 
    return; 

    // fulfills_condition1 holds here. 

    if (!fulfills_condition_2) 
    // error msg here. 
    return; 

    // Both conditon1 and condition2 hold here. 

    if (!fulfills_condition_3) 
    // error msg here. 
    return. 
2

Jeśli to, co przeszkadza są kaskadowe if s, można pójść do jednego z następujących powodów:

Korzystanie wartość logiczną:

bool is_valid = true; 
string error = ""; 
if (!condition_one) { 
    error = "my error"; 
    is_valid = false; 
} 

if (is_valid && !condition_two) { 
    ... 
} 

... 

if (!is_valid) { 
    cout << error; 
} else { 
    // Do something with valid input 
} 

Korzystanie wyjątkami:

try { 
    if (!condition_one) { 
    throw runtime_error("my error"); 
    } 

    if (!condition_two) { 
    ... 
    } 

    ... 

} catch (...) { 
    // Handle your exception here 
} 
1

Jeśli ta zostanie ponownie użyty w kilku miejscach, zrobię DSL:

Validator inputType1Validator = 
    Validator.should(fulfill_condition_1, error_message_1) 
      .and(fulfill_condition_2, error_message_2) 
      .and(fulfill_condition_3, error_message_3) 

inputType1Validator.check(input); 
Powiązane problemy