2010-08-24 10 views
2

Dans le projet actuel, il y a beaucoup de méthode GetData(), qui obtiennent différents types de données à partir de base de données manuscrite à l'exécution, et les définir dans différents champs d'une classe. Les projets ont alors de telles méthodes.Comment optimiser/refactoriser un tel code?

void GetData(Datatype type, int& value); 
void GetData(Datatype type, double& value); 
void GetData(Datatype type, long& value); 
void GetData(Datatype type, longlong& value); 
.... 

Il y a beaucoup de types de données, donc, ces méthodes sont souvent appelées avec un interrupteur avec beaucoup de branches.

void GetData(Datatype type, int& value) 
{ 
    switch(type) 
    { 
     Type1: 
     value = GetDataFromDB1(TYPE1); 
     Type2: 
       value = .. //get from different source 
     ... 

    } 

}

void GetData(Datatype type, double& value) 
.... 

Comme vous le voyez, les s du GetData() sont classés selon le deuxième param. Et dans chaque GetData(), il y a beaucoup de branches. Est-ce une méthode raisonnable pour obtenir des données?

+4

Il y a trop peu de contexte pour même faire une supposition éclairée, mais il semble que cela pue d'un besoin de modèles. – sbi

+0

'boost :: any'? Ou peut-être 'boost :: variant'? – jalf

Répondre

2

Pour répondre à "la meilleure façon de refactoriser cela" prendrait plus de contexte. Par exemple, il est peut-être approprié de changer la façon dont les données sont stockées en plus de la façon dont elles sont récupérées comme vous le montrez. Je doute que cette structure de code ait besoin d'optimisation.

0

Désolé, programmeur Java à venir :)
J'ai 2 solutions ici:

  1. Si vous voulez modifier le code pas beaucoup, vous pouvez mettre Datatypes et leurs opérations pertinentes dans une Carte. Si long switch(type) déclaration pourrait être une déclaration map.get(type).

  2. Si plus de façon décente, utilisez Polymorphisme. Vous pouvez définir une interface pour DBOperations, chaque DBOperation spécifique pouvant être définie dans sa classe implémentée. Donc GetData juste besoin d'invoquer DBOperation interface. C'est une idée approximative .

-1

Je ne sais pas, si je comprends les choses, mais cela pourrait aider

typedef int Datatype; 

template <Datatype d, class T> struct Wrap{ 
    Wrap(T (*p)(Datatype)) : mp(p){} 
    template<class T> void GetData(T &value){ 
     value = (*mp)(d); 
    }; 
    T (*mp)(Datatype); 
}; 

int GetDataFromDB(Datatype){ 
    return 0; 
} 

int main(){ 
    Wrap<0, int> wi0(GetDataFromDB); 
    int val; 
    wi0.GetData(val); 
} 
+0

Une fois que vous avez de toute façon le type fixé dans votre template 'Warp', vous pouvez changer' GetData() 'pour l'utiliser plus facilement:' int val = w10.GetData() '. Le faire en tant qu'argument de fonction n'a très probablement été fait que pour faciliter la déduction des arguments du modèle. – sbi

+0

@sbi: vrai, mais j'ai essayé d'être aussi synchronisé que possible avec le code original (qui renvoie la valeur par référence – Chubsdad

+1

-1: L'introduction d'un ensemble d'objets en correspondance 1: 1 avec des fonctions existantes ne constitue pas un refactoring. C'est juste de l'obfuscation. – Potatoswatter

0

On dirait que vous êtes une interface outgrowing SQL personnalisée. Regardez dans les bibliothèques SQL C++ existantes. Malheureusement, je ne peux pas en recommander (la dernière fois que j'en avais besoin, j'en ai écrit une nouvelle à des frais déraisonnables), mais voir la question connexe C++ SQL database library comparison.

En outre, libpqxx, le client C++ PostgreSQL officiel, semble très agréable. Hmm, en regardant autour, je n'arrive pas à trouver une bibliothèque avec un support générique pour struct s comme ce que j'ai écrit. Il doit y en avoir quelques-uns ... vous devriez pouvoir brancher vos tables et vos en-têtes (avec une petite modification, peut-être) et obtenir un code d'interface automatique.

0

Vous pourriez vouloir le refactoriser pour le rendre plus maintenable.

Le refactoring pour l'optimisation n'aura probablement aucun avantage, ou négatif, sauf si vous avez montré qu'il s'agit d'un problème de performance, par profilage.