2017-12-20 7 views

Antwort

2

Code wäre leichter zu lesen, während es nur als „komplex“ ist (während es ist nicht wirklich so komplex), wenn Sie:

  • eine switch-Anweisung verwenden
  • den Wert von GetNodeName Extrakt () vorher
  • den Wert extrahieren, indem getElementValueAfterNullCheckWithTrim() zurück vorher

    String value = formatter.getElementValueAfterNullCheckWithTrim((Element) eachTag); 
    String nodeName = eachTag.getNodeName(); 
    
    switch (nodeName) { 
        case ONE: 
         myclassDto.setOne(value); 
         break; 
        case TWO: 
         myclassDto.setTwo(value); 
         break; 
        ... 
    } 
    

Edit: Vielleicht möchten Sie Ihre DTO Refactoring so ist es einfacher zu bedienen, wie

myclassDto.setValue(nodeName, value) 
+0

Der DTO Refactoring Teil ist sehr wichtig in Anbetracht seiner tatsächlichen Architektur. –

+0

Wenn ich Schalter verwende, reduziere die Komplexität von 19 auf 17. Aber muss auf 10 reduziert werden. – user3431624

+0

Wie ich in meiner Antwort sagte, ist die Verwendung von 'switch' genauso" komplex "wie die Verwendung von' if'. Es ist einfach lesbarer. Und was ist mit der Umgestaltung des DTO? Wenn Ihr DTO Daten nicht effizient akzeptiert, d. H. Es hat 100 set ***() -Methoden, bezweifle ich, dass Sie eine niedrigere Komplexität erhalten. – SurfMan

1

ich eine Abbildung von Strings auf die Funktionen definieren, würden sie mit entsprechen. Dies kann statisch sein.

Dann können Sie die Zuordnungen durchlaufen, die entsprechende (filter) finden und die Funktion anwenden.

private static final Map<String, BiConsumer<MyClassDto, Element>> MAPPING = new HashMap(); 

static 
{ 
    mapping.put(ONE, MyClassDto::setOne); 
    mapping.put(TWO, MyClassDto::setTwo); 
    //... 
    mapping.put(SIX, MyClassDto::setSix); 
} 


//... 

MAPPING.entrySet().stream() 
    .filter(pair -> pair.getKey().equalsIgnoreCase(eachTag.getNodeName())) 
    .map(Map.Entry::getValue) 
    .forEach(func -> func.accept(
     myClassDto, 
     formatter.getElementValueAfterNullCheckWithTrim((Element) eachTag) 
    )); 

Möglicherweise möchten Sie den Fall betrachten, wo MAPPING verschiedene Schlüssel enthalten kann, die gleich behandelt werden durch equalsIgnoreCase (z „AAA“ und „aaa“).

Eine Lösung ist die Verwendung von findFirst().ifPresent() anstelle von forEach (wie von daniu vorgeschlagen), aber dies kann einige Fehlerfälle maskieren, also verwenden Sie es mit Vorsicht.

+0

Das wäre mein Ansatz gewesen, aber Sie können 'forEach' nicht mit äquivalentem Ergebnis tun; Es können mehr als eine Zuordnung ausgelöst und mehr als ein "BiConsumer" aufgerufen werden. Daher 'findFirst(). IfPresent()'. Auch "getNodeName" könnte sich außerhalb des Streams befinden. – daniu

+0

@daniu Das Problem, das ich damit habe, ist, dass 'findFirst' einige schwer zu findende Fehler maskieren könnte. Wenn Sie zwei Mappings mit unterschiedlichen Case-Strings (zB "AAA" und "aaa") haben und "HashMap" keine vorhersagbare Iterationsreihenfolge hat, kann die Verwendung von "findFirst" dazu führen, dass zwischen den einzelnen Funktionen hin- und hergewechselt wird. Dies wäre unglaublich schwer zu finden. Wenn Sie sicherstellen möchten, dass es keine zwei "gleichen" Zuordnungen gibt, sollten Sie eine Funktion schreiben, die über die Schlüssel iteriert und nach Duplikaten sucht. – Michael

+0

Einverstanden, aber wenn Sie "aaa" und "AAA" mit Ihrem Code hinzufügen, werden Sie beide 'BiConsumer' aufrufen. Würden sie zB die Übereinstimmung zu einer Datenbank mit einer Eindeutigkeitsbedingung hinzufügen, würde dies fehlschlagen. Ich würde 'findFirst' lieber mit' LinkedHashMap' für 'MAPPING' verwenden (was meiner Meinung nach eine deterministische Iteration liefert). Nicht, dass irgendetwas davon für den einfachen Fall von OP eine Rolle spielt;) – daniu

Verwandte Themen