web-dev-qa-db-fra.com

Motif de conception pour traiter un énorme fichier CSV - Java

Je suis en train d'apprendre des modèles de conception dans Java et travaillez également sur un problème dans lequel je dois gérer un nombre énorme de demandes diffusant dans mon programme à partir d'un énorme fichier CSV sur le disque. Chaque ligne CSV est une demande. et le premier champ de chaque ligne indique le type de message. Il existe 7 types de messages, chacun devrait être traité différemment.

Le code est quelque chose comme ce qui suit:

class Handler {
    private CustomClass {….}
    Map<String, CustomClass> map = new HashMap<String, CustomClass>();
    Public void runFile() {
        // Read the huge CSV file with millions of records, line by line
        // for each line, get the string before the first comma (say X)
        switch (X) {
        case 1 : myMethod1(….); break;
        case 2 : myMethod2(….); break;
        case 3 : myMethod3(….); break;
        // ...
        default: // ...
        }
    }
    // Methods 1, 2, 3 declarations
}

NOTE 1: Certaines méthodes affectent la carte et les autres ne le font pas.
[.____] Note 2: Chaque demande (méthode) utilise différentes variables de la ligne CSV et exécute une logique différente.
[.____] NOTE 3: Les demandes/méthodes ne sont pas connectées; I.e. myMethod2() ne suit pas logiquement myMethod1().

Maintenant ma question - Qu'est-ce qu'un modèle de conception approprié pour ce problème? Est-ce bien si je garde la logique entière dans une classe (semblable au code ci-dessus) sans changer?

5
Shad

Je suppose que l'exemple de code que vous affiche est juste un exemple simplifié et que le vrai problème est plus complexe, de manière à mériter d'utiliser un motif.

  • Faire CustomClass une classe externe (*).
  • Avoir plusieurs processeurs qui implémentent la même interface
  • Avoir une carte des processeurs utilisant l'entier qui identifie le format de la ligne CSV comme clé (vous l'appelez X).
  • Récupérez un processeur de la carte (avec la clé de correction) et faites-la traiter la ligne.
  • Ceci similaire à modèle de stratégie , il définit une famille d'algorithmes, encapsule chaque algorithme et rend les algorithmes interchangeables dans cette famille.

Avantages: Flexibilité, si vous créez la carte des processeurs en dehors du gestionnaire et transmettez-la dans le constructeur, plus de processeurs peuvent être ajoutés plus tard et le gestionnaire n'aura pas besoin à modifier (par exemple pour ajouter un nouveau cas la structure de commande de commutation).

enter image description here

(*) Vous pouvez obtenir les mêmes résultats que l'interface et les processeurs ainsi que la classement personnalisée en tant que classes/interfaces intérieures à l'intérieur du gestionnaire, mais elle polluerait beaucoup la solution.

==> CustomClass.java <==

public class CustomClass {}

==> imessageprocessor.java <==

import Java.util.Map;

public interface IMessageProcessor {
    public void processLine(Map<String, CustomClass> map, String line);     
}

==> processora.java <==

import Java.util.Map;

public class ProcessorA implements IMessageProcessor {
    @Override
    public void processLine(Map<String, CustomClass> map, String line) {
        // TODO Auto-generated method stub
    }
}

==> processorb.java <==

import Java.util.Map;

public class ProcessorB implements IMessageProcessor {
    @Override
    public void processLine(Map<String, CustomClass> map, String line) {
        // TODO Auto-generated method stub
    }
}

==> processorc.java <==

import Java.util.Map;

public class ProcessorC implements IMessageProcessor {
    @Override
    public void processLine(Map<String, CustomClass> map, String line) {
        // TODO Auto-generated method stub
    }
}

==> Handler.java <==

import Java.util.HashMap;
import Java.util.Map;

public class Handler {
    private Map<String, CustomClass> map = new HashMap<String, CustomClass>();
    private Map<Integer,IMessageProcessor> processors = new HashMap<Integer,IMessageProcessor>();
    public processFile(){
        // store the processors in their map with the appropiate keys 
        processors.put(1, new ProcessorA());
        processors.put(2, new ProcessorB());
        processors.put(3, new ProcessorC());

        // Read the huge CSV file with millions of records, line by line
        // for each line, get the string before the first comma (say x)
        processors.get(x).processLine(map,line);
    }
}

Remarque: Vous voudrez peut-être valider d'abord si le processeur de la clé x existe, et il ne relève pas d'un processeur par défaut, par exemple, stocké Avec Key -1, ou toute autre valeur garantie pour ne pas exister dans le fichier CSV.

5
Tulains Córdova

Gardez-le simple, stupide (baiser)

Qu'est-ce qu'un modèle de conception approprié pour ce problème? Est-ce bien si je garde la logique entière dans une classe (semblable au code ci-dessus) sans changer?

Oui, laissez simplement toute la logique dans cette classe. Ne cherchez pas à appliquer des modèles de conception exotiques simplement parce que les modèles de conception sont tiftys. La seule chose que vous accomplirez avec un modèle de conception consiste à rendre les choses compliquées de manière inutile.

5
Winston Ewert