2017-01-19 1 views
5

Ich muss die Logik mit vielen Bedingungen (bis zu 30 Bedingungen) in einem Regelsatz mit vielen wenn sonst Bedingungen schreiben und es könnte zwischen oder nach allen Bedingungen enden.Benötigen Sie Entwurfsvorschläge für verschachtelte Bedingungen

Hier ist der Beispielcode, den ich mit einem möglichen Szenario versucht habe. Dies gibt mir ein Ergebnis, aber es sieht nicht gut aus und jede kleine Verfehlung in einer Bedingung würde ewig dauern, um sie zu verfolgen.

Was ich bisher versucht habe, ist, Gemeinsame Bedingungen herauszunehmen und einige Methoden zu überarbeiten. Versucht, eine Schnittstelle mit Bedingungen und verschiedenen Mengen zu erstellen, würde dies implementieren.

Wenn Sie einen Vorschlag haben, dies zu entwerfen, würde mir helfen. Nicht auf der Suche nach einer detaillierten Lösung, aber auch ein Hinweis wäre großartig.

private Boolean RunCondition(Input input) { 
    Boolean ret=false; 
    //First if 
    if(input.a.equals("v1")){ 
     //Somelogic1(); 
     //Second if 
     if(input.b.equals("v2")) 
      //Third if 
      if(input.c >1) 
       //Fourth if 
       //Somelogic2(); 
       //Go fetch key Z1 from database and see if d matches. 
       if(input.d.equals("Z1"))       
         System.out.println("Passed 1"); 
        // Fourth Else 
        else{ 
         System.out.println("Failed at fourth"); 
        } 

      //Third Else 
      else{ 
       if(input.aa.equals("v2")) 
        System.out.println("Failed at third"); 
       } 
     //Second Else 
     else{ 
      if(input.bb.equals("v2")) 
       System.out.println("Failed at second"); 
      } 
    } 
    //First Else 
    else{ 
     if(input.cc.equals("v2")) 
      System.out.println("Failed aat first"); 
     } 

    return ret; 
} 

public class Input { 
    String a; 
    String b; 
    int c; 
    String d; 
    String e;  
    String aa; 
    String bb; 
    String cc; 
    String dd; 
    String ee; 

} 
+2

Es wäre viel einfacher, wenn Sie a) es sinnvoll einbetteten, b) "else if" benutzten. –

+0

Dies ist weder oop noch Design-Muster. Es geht nur darum, prozeduralen Code zu schreiben. –

+0

Ich denke, um die richtige Antwort für Ihr Problem zu finden, müssen Sie erklären, wie Sie mit dieser Logik enden. Vielleicht können Sie das Filter-Design-Muster verwenden oder die richtige OO kann Ihr Problem lösen – Mzf

Antwort

1

Die Strömung ist kompliziert, weil Sie einen normalen Fluss, plus viele mögliche Ausnahme fließt, wenn einige der Werte sind die Ausnahme (z ungültig).

Dies ist ein perfekter Kandidat für die Handhabung mit einem Versuch/fangen/schließlich Block.

Ihr Programm kann in neu geschrieben wird folgende:

private Boolean RunCondition(Input input) { 
    Boolean ret=false; 
    try { 
     //First if 
     if(!input.a.equals("v1")) { 
      throw new ValidationException("Failed aat first"); 
     } 
     //Somelogic1(); 

     //Second if 
     if(!input.b.equals("v2")) { 
      throw new ValidationException("Failed at second"); 
     } 
     //Somelogic2() 

     //Third if 
     if(input.c<=1) { 
      throw new ValidationException("Failed at third"); 
     } 

     //Fourth if 
     //Somelogic2(); 
     //Go fetch key Z1 from database and see if d matches. 
     if(!input.d.equals("Z1")) { 
      throw new ValidationException("Failed at fourth"); 
     } 
     System.out.println("Passed 1"); 

    } catch (ValidationException e) { 
      System.out.println(e.getMessage()); 
    } 

    return ret; 
} 

wo Sie Ihre eigenen ValidationException (wie unten) definieren können, oder Sie können einen Teil der bestehenden Standard-Ausnahme wie RuntimeException

class ValidationException extends RuntimeException { 

    public ValidationException(String arg0) { 
     super(arg0); 
     // TODO Auto-generated constructor stub 
    } 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

} 
Wiederverwendung

Sie können mehr darüber in

https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html

lesen
+0

Dies ist eine interessante Option. Ich habe gezögert, Exception zu verwenden, da es Speicher auffressen wird, aber es wird eine Chance geben. – Paresh

+1

Ausnahmen sind nicht notwendig und sollten nicht so verwendet werden. Eine kleine Variation hierzu finden Sie unter [meine Antwort] (http://stackoverflow.com/a/41751365/3788176), die viel einfacher und schneller ist. –

+0

Das Dogma ist, dass Ausnahmen nicht für die Flusskontrolle verwendet werden sollten, und daher gibt es stilistische Gründe, warum diese Lösung nicht übernommen werden sollte. – scottb

1

Machen Sie eine eigene Klasse für die Bedingung:

package com.foo; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class App 
{ 
    static class Condition<T> { 
     final int idx; 
     final T compareValue; 
     public Condition(final int idx, final T compareValue) { 
      this.idx = idx; 
      this.compareValue = compareValue; 
     } 
     boolean satisfies(final T other) { 
      return other.equals(compareValue); 
     } 

     int getIdx() { 
      return idx; 
     } 
    } 
    public static void main(String[] args) 
    { 
     final List<Condition<String>> conditions = new ArrayList<Condition<String>>(); 
     conditions.add(new Condition<String>(1, "v1")); 
     conditions.add(new Condition<String>(2, "v2")); 
     final List<String> inputs = new ArrayList<String>(Arrays.asList("v1", "xyz")); 
     boolean ret = true; 
     for (int i = 0; i < inputs.size(); i++) { 
      if (!conditions.get(i).satisfies(inputs.get(i))) 
      { 
       System.out.println("failed at " + conditions.get(i).getIdx()); 
       ret = false; 
       break; 
      } 
     } 
     System.out.println("ret=" + ret); 
    } 
} 
1

Denken Sie an jeder Regelprüfung als Objekt oder als eine Strategie, ob oder ob nicht kehrt der Regel passiert. Jede Überprüfung sollte dieselbe IRuleCheck-Schnittstelle implementieren und ein RuleCheckResult zurückgeben, das angibt, ob die Überprüfung bestanden wurde oder der Grund für einen Fehler.

public interface IRuleCheck 
{ 
    public RuleCheckResult Check(Input input); 
    public String Name(); 
} 

public class RuleCheckResult 
{ 
    private String _errorMessage; 
    public RuleCheckResult(){}//All Good 
    public RuleCheckResult(String errorMessage) 
    { 
     _errorMessage = errorMessage; 
    } 
    public string ErrorMessage() 
    { 
     return _errorMessage; 
    } 
    public Boolean Passed() 
    { 
     return _errorMessage == null || _errorMessage.isEmpty(); 
    } 

} 

public class CheckOne implements IRuleCheck 
{ 
     public RuleCheckResult Check(Input input) 
     { 
      if (input.d.equals("Z1")) 
      { 
      return new RuleCheckResult();//passed 
      } 
      return new RuleCheckResult("d did not equal z1"); 
     } 
     public String Name(); 
} 

Dann können Sie einfach eine Liste von Regeln und Schleife durch sie bauen, und entweder springen, wenn einer ausfällt, oder eine Liste von Fehlern kompilieren.

for (IRuleCheck check : checkList) 
{ 
    System.out.println("checking: " + check.Name()); 
    RuleCheckResult result = check.Check(input); 
    if(!result.Passed()) 
    { 
     System.out.println("FAILED: " + check.Name()+ " - " + result.ErrorMessage()); 
     //either jump out and return result or add it to failure list to return later. 
    } 
} 

Und der Vorteil, dass die Schnittstelle zu verwenden, ist, dass die Kontrollen so kompliziert oder einfach, wie notwendig sein können, und Sie können für die Überprüfung eines beliebige Kombination von Regeln in beliebiger Reihenfolge beliebige Listen erstellen.

1

@leeyuiwah's answer hat eine klare Struktur der bedingten Logik, aber Ausnahmen sind nicht das richtige Werkzeug für den Job hier.

Sie sollten keine Ausnahmen verwenden, um nicht außergewöhnliche Bedingungen zu bewältigen. Zum einen sind Ausnahmen sehr aufwändig zu konstruieren, da man den Aufrufstapel hochlaufen muss, um die Stack-Trace zu erstellen. aber Sie brauchen den Stack-Trace überhaupt nicht.

Auschecken Effektive Java 2nd Ed Punkt 57: "Verwenden Sie Ausnahmen nur für Ausnahmezustände" für eine detaillierte Diskussion, warum Sie Ausnahmen wie diese nicht verwenden sollten.

Eine einfachere Möglichkeit ist, ein wenig Hilfsmethode zu definieren:

private static boolean printAndReturnFalse(String message) { 
    System.out.println(message); 
    return false; 
} 

Dann:

if(!input.a.equals("v1")) { 
    return printAndReturnFalse("Failed aat first"); 
} 
// etc. 

die ich denke, ist ein einfacher; und es wird viel schneller sein.

Verwandte Themen