2017-09-20 4 views
0

J'ai créé trois méthodes readLong, readInt et readDouble qui font essentiellement la même chose. La seule différence est la méthode appelée par un scanner. Comment puis-je réduire le code en double en les transformant tous en une seule méthode?Réduire la duplication de code lors de la lecture de différents types de numéros depuis la console

public long readLong(String description) 
    { 
     System.out.println(description); 
     long nrToReturn = 0; 
     boolean acceptedValue = false; 

     do { 
      System.out.println(); 
      System.out.print("Choose one: "); 
      try 
      { 
       nrToReturn = consoleScanner.nextLong(); //Only line thats different except return value 
       acceptedValue = true; 
      }catch(Exception e) 
      { 
       acceptedValue = false; 
       consoleScanner.nextLine(); 
      } 
     }while (!acceptedValue); 

     consoleScanner.nextLine(); 
     return nrToReturn; 
    } 
+0

Poster cette question sur [révision du code] (https://codereview.stackexchange.com/). –

+0

Jetez un oeil aux types génériques en Java – Michu93

+0

Comment l'appelant de ces méthodes sait-il lequel invoquer? –

Répondre

2

Ici nous allons avec une idée:

import java.util.Scanner; 

public class ScannerTest { 

    private Scanner consoleScanner; 

    public ScannerTest() { 
     consoleScanner = new Scanner(System.in); 
    } 

    @SuppressWarnings("unchecked")  
    private <T extends Number> T readType(String description, Class<T> desiredType) { 
     System.out.println(description); 
     Number result = null; 

     while (result == null) { 
      System.out.println(); 
      System.out.print("Choose one: "); 
      try { 
       if (Integer.class.equals(desiredType)) { 
        result = new Integer(consoleScanner.nextInt()); 
       } else if (Long.class.equals(desiredType)) { 
        result = new Long(consoleScanner.nextLong()); 
       } 
      } catch(Exception e) { 
       consoleScanner.nextLine(); 
      } 
     } 

     consoleScanner.nextLine(); 
     return (T) result; 
    } 

    public long readLong(String description) { 
     return this.readType(description, Long.class); 
    } 

    public int readInt(String description) { 
     return this.readType(description, Integer.class); 
    } 

    public static void main(String[] args) { 
     ScannerTest t = new ScannerTest(); 
     t.readLong("Reading a long value..."); 
     t.readInt("Reading an integer value..."); 
    } 
} 

Mise à jour, suivant @ Michu93 idée d'une méthode transparente:

import java.util.Scanner; 

public class ScannerTest { 

    private Scanner consoleScanner; 

    public ScannerTest() { 
     consoleScanner = new Scanner(System.in); 
    } 

    @SuppressWarnings("unchecked") 
    public <T extends Number> T readNumber(String description) { 
     System.out.println(description); 
     Number result = null; 

     while (result == null) { 
      System.out.print("\nChoose one: "); 
      String textRead = consoleScanner.next(); 

      try { 
       result = new Integer(textRead); 
      } catch(Exception e1) { 
       try { 
        result = new Long(textRead); 
       } catch (Exception e2) { 
        try { 
         result = new Double(textRead); 
        } catch (Exception e3) { 
        } 
       } 
      } 
      consoleScanner.nextLine(); 
     } 

     return (T) result; 
    } 

    public static void main(String[] args) { 
     ScannerTest t = new ScannerTest(); 
     for (int i = 0; i < 3; i++) { 
      Number input = t.readNumber(i + ": Reading int, long or double..."); 
      System.out.println("Input class: " + input.getClass().getCanonicalName()); 
      System.out.println("Input value: " + input); 
     } 
    } 
} 
+0

Edit: Je pensais la même chose à propos de l'utilisation de génériques au lieu d'Object, comme l'a souligné @ Michu93. Mais je ne pense pas qu'il soit possible de faire une telle méthode publique [public static T readNumber (String description)] sans indiquer quel type d'entrée est nécessaire, sauf si vous définissez une hiérarchie entre les types et essayez de lire chaque tapez jusqu'à succès à chaque fois que la méthode est appelée. Mise à jour de ma réponse pour l'adapter à l'idée . [Je ne peux pas commenter sur le fil d'origine car je ne suis pas encore 50 pts, désolé]. –