2017-08-21 2 views
0

J'ai une instruction switch qui traverse un fichier json et fait des choses différentes en fonction de l'attribut dans le fichier. Par exemple:Java 8 refactor instruction switch qui fait des choses différentes pour chaque cas

dataMap.forEach((k, v) -> { 
     Product product = new Product(); 
     ProductLine productLine = new ProductLine(); 
     Vendor currentVendor = new Vendor(); 

     // Step over each atttribute in the line of the file 
     v.forEach((k2, v2) -> { 
      switch(k2) { 
       case "Product Class": { 
        Set<ProductCategory> categories = new HashSet<>(); 
        try { 
         List<String> categoryList = Arrays.asList(v2.split(",")); 
         categoryList.forEach(it ->{ 
          ProductCategory category = ProductCategory.loadTypeByValue(it.trim()); 
          categories.add(category); 
         });      
         product.setProductCategories(categories); 
        } catch (Exception e) { 
         // 
        } 
        break; 
       }     
       case "Product Name": { 
        product.setName(v2); 
        productLine.setName(v2); 
        break; 
       } 
       case "SKU": { 
        product.setSKU(v2); 
        break; 
       } 
       case "Name": { 
        vendor.setName(v2); 
       } 
      .... 

Étant donné que ces déclarations de cas de travail avec des objets différents (Product, ProductLine et Vendor), et chaque cas nécessite parfois un Producer, Consumer ou Function interface, comment puis-je factoriser le commutateur entier (de préférence en utilisant Lambdas de quelque sorte)? J'ai pensé à utiliser une carte, avec la clé étant le cas, comme "Classe de produit", mais quelle serait la valeur?

Map <String, ?> = new HashMap<>(); 

Merci pour toute aide!

+0

Tu ne peux pas créer une classe qui reflète la structure JSON et analyser juste l'entrée? – PanBrambor

Répondre

-1

Il est juste idée, mais pourquoi ne pas faire quelque chose comme ceci:

dataMap.forEach((k, v) -> { 
     Product product = new Product(); 
     ProductLine productLine = new ProductLine(); 
     Vendor currentVendor = new Vendor(); 

    List<Entry<K,V>> vSet = v.entrySet(); 
    vSet.stream().filter((v)->"Product Class".equals(v.getKey())) 
      .foreach((v)->addCategoriesToProduct(product, v.getKey(), v.getValue())); 


    vSet.stream().filter(((v)->"Product Name".equals(v.getKey())) 
      .foreach((v)->fillProductName(product, v.getValue())); 


    vSet.stream().filter((v)->"SKU".equals(v.getKey())) 
      .foreach((v)->fillProductName(product, v.getValue())); 

Edit: Peut-être qu'il veut de somethink comme celui-ci;

r = new ProductAttributeResolver(v.entrySet()); 

product.setCategories(r.getAllCategories()); 
product.setName(r.getProductName()); 
... 

alors getProductName se ressemble:

return vSet.stream().filter(((v)->"Product Name".equals(v.getKey())) 
      .map((v)->v.getValue()) 
      .findFirst() 
      .orElse(null) 
+0

Cela semble plutôt cool, mais mon chef n'aime pas les déclarations forEach. Il m'a dit d'utiliser un pattern créateur/résolveur, et je n'ai aucune idée de ce que c'est! – user1660256

+1

Aimer ou non n'a aucun impact sur la façon dont le code fonctionne, dites-lui de saisir la réalité. ;) – PanBrambor

+1

N'as-tu pas juste triplé le nombre d'itérations? – GhostCat

-1

Eh bien, je pense avoir répondu à ma propre question. Je définissais chaque cas comme BiConsumer<String, Object>(), et je suis la mise en place d'un Map pour chaque attribut et son BiConsumer comme ceci:

final static Map<String, BiConsumer<String, Object>> attributeMap = new HashMap<>(); 

private BiConsumer<String, Object> setVendorName = new BiConsumer<String, Object>() { 
    @Override 
    public void accept(String value, Object obj) { 
     ((Vendor)obj).setName(value); 
    } 
}; 

attributeMap.put("Vendor Name", setVendorName); 
+0

Vous n'avez pas besoin d'utiliser BiConsumer. Vous pouvez écrire votre propre interface, avec une méthode qui accepte une valeur, un produit et un fournisseur. – VGR

+0

Merci. Cependant, je n'ai pas toujours besoin des deux paramètres. Donc j'ai juste ajouté une if-statement dans le for-each. – user1660256

+1

N'utilisez pas d'objet. Pensez aux autres en utilisant votre code. –