2012-11-08 9 views
6

Switch-Case-Anweisungen sind gut, verschachtelte if-Anweisungen zu ersetzen, wenn wir die gleiche Bedingung, aber unterschiedliche Kriterien haben. Aber was ist ein guter Ansatz, wenn diese verschachtelten if-Anweisungen alle unterschiedliche und einzigartige Bedingungen haben? Habe ich alternative Optionen, um ein Dutzend if else-Anweisungen zu ersetzen, die ineinander verschachtelt sind?Ersetzen von If Else eindeutige bedingte geschachtelte Anweisungen

Beispielcode:

  • Hinweis: Ich weiß, das extrem unleserlich ist - was der Sinn ist.
  • Hinweis: Alle Bedingungen sind einzigartig.

...

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

Wenn Sie in dieser Situation sind, sind die Chancen, dass Ihr Design schrecklich fehlerhaft ist. –

+1

Wie Jordan Kaye sagt + Wenn Sie wirklich solche komplexen Bedingungen haben, wenn-sonst wird der einfachste Weg sein, dies zu tun –

+0

Ich stimme Herrn Kaye. Es gibt ein paar richtige Antworten darauf, je nachdem, was die Bedingung ist, das ist jedoch keiner von ihnen. Es ist ein Fehlerfest, versuche einen Einheitentest dafür zu schreiben, es könnte ein paar Dinge vorschlagen. –

Antwort

1

Ich musste überprüfen, das war Stackoverflow nicht DailyWTF, als ich den Code sah !!

Die Lösung ist, die Architektur zu ändern und Schnittstellen und Polymorphie zu verwenden, um alle Bedingungen zu umgehen. Allerdings, dass vielleicht ein großer Job und aus dem Rahmen einer akzeptablen Antwort, so Ich werde einen anderen Weg gibt irgendwie wechseln Aussagen mit einzigartigen Bedingungen verwenden:

[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

Der beste Ansatz ist in diesem Fall das Ding in entsprechend benannten separaten Verfahren zerhacken.

+1

Das Beste? Warum nicht eine Regel-Engine? –

+1

Es ist das Gleiche. Es sieht nur anders aus. – Tar

1

Aus meiner Sicht gibt es zwei Hauptmethoden, verschachtelte Bedingungen zu beseitigen. Die erste ist in mehr Sonderfällen verwendet werden, wenn wir nur eine Bedingung in jeder verschachtelten Bedingungen haben wie hier:

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

wir können Rückkehr mit nur von der entgegengesetzten Zustand gehen:

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

Die zweite Man verwendet eine Zustandszerlegung und kann als universeller als die erste behandelt werden. Im Fall, wenn wir eine Bedingung Struktur wie diese, zum Beispiel:

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

Wir haben eine Variable für jede besondere Bedingung wie hier umsetzen können:

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

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

Aber wie geht man damit um? – Paparazzi

+0

Ja, ich stimme zu, dass dies nur für einen speziellen Fall funktioniert, wie in meinem Beispiel wo Bedingungen ohne "sonst" sind. Wenn Bedingungen verschachtelt sind und ohne dass wir viele verschachtelte Zweige eliminieren können. – apros

0

Wenn das wirklich die Business-Logik dann ist die Syntax ist OK. Aber ich habe noch nie eine so komplexe Geschäftslogik gesehen. Erstellen Sie ein Flussdiagramm und sehen Sie, ob das nicht vereinfacht werden kann.

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

mit

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

aber wieder einen Schritt zurück und überprüfen Sie die Konstruktion ersetzt werden. Brauchen mehr als nur ein anderes, wenn aufzuräumen.

+0

Persönliche Sache, aber ich habe das nie gemocht, ich bekomme immer einen unkontrollierbaren Drang, viel mehr Klammern hinzuzufügen und Dinge einzumessen. :) –

1

@Tar schlug eine Möglichkeit vor, es zu betrachten. Ein anderer könnte sein.

Invertieren Sie es.

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

konnte

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

So tun Methode, um die minimale Anzahl von Tests macht, wenn überhaupt die scheitern es nichts tut.

Sie können es ein bisschen klüger machen, wenn Sie aus der Reihenfolge auf verschiedene Arten ausbrechen möchten.

Keine Ahnung, ob es für Sie funktionieren würde, aber das Testen der Bedingungen zu delegieren ist oft genug von einer neuen Sichtweise, dass ein simplifizierender Faktor wie von Zauberhand erscheint.

0

Ich fühle deinen Schmerz.

Meine Situation erforderte das Schreiben vieler (> 2000) Funktionstests, die vom Kunden für ein großes, teures Gerät spezifiziert wurden. Während die meisten (> 95%) dieser Tests einfach sind und eine direkte Pass/Fail-Prüfung haben, fallen Dutzende in die "Mehrfachverschachtelung, wenn dies etwas anderes tut" in Tiefen, die ähnlich oder schlechter sind als Ihre.

Die Lösung, die ich fand, war, Windows Workflow in meiner Testanwendung zu hosten.

Alle komplexen Tests wurden Workflows, die ich mit den Ergebnissen zurück zu meiner Test-App gemeldet laufen.

Der Kunde war glücklich, weil sie die Fähigkeit hatten:

  1. die Testlogik Verify (hart für nicht-Programmierer bei tief verschachtelt sucht if/else C# - einfach in einer grafischen Flussdiagramm der Suche)
  2. bearbeiten grafisch
  3. Tests neue Tests hinzufügen

Hosting Windows Workflow (in .NET 4/4,5) ist sehr einfach - auch wenn es Ihnen eine Weile dauern kann, Ihren Kopf um „Kommunikation“ zu bekommen sein zwischen den Workflows und Ihrem Code - hauptsächlich, weil es mehrere Möglichkeiten gibt, dies zu tun.

Viel Glück