2011-04-19 3 views
3

Je cours avec des méthodes mises en œuvre comme suit:Pouvons-nous refactoriser ces méthodes?

void methodOne() { 
    try { 
     getHelper().doActionOne(); 
    } catch (Exception ex) { 
     throw new CustomException(ex); 
    } 
} 

void methodTwo() { 
    try { 
     getHelper().doActionTwo(); 
    } catch (Exception ex) { 
     throw new CustomException(ex); 
    } 
} 

void methodThree() { 
    try { 
     getHelper().doActionThree(); 
    } catch (Exception ex) { 
     throw new CustomException(ex); 
    } 
} 


void methodFour; 
void methodFive; 
... 

Y at-il une meilleure façon de le faire? Ces codes me rendent mal à l'aise.

EDIT: Désolé pour un exemple non clair. Je classe implémentant GenericDao avec Hibernate, le code réel est quelque chose comme ceci:

class GenericDaoImpl<T, PK> { 

    PK create(T object) { 
     try { 
      getSession().save(object); 
     } catch(Exception ex) { 
      throw new DataAccessLayerException(ex);// wrap any exception to my exception 
     } 
    } 

    T read(PK id) { 
     try { 
      getSession().get(T.class, id); 
     } catch (Exception ex) { 
      throw new DataAccessLayerException(ex); 
     } 

    } 

    void update(T object); 
    void delete(T object); 

} 
+3

Pourriez-vous expliquer le contexte dans lequel ces méthodes sont appelées? – Ammu

+0

Pourquoi le code vous rend-il mal à l'aise? Je ne vois rien de particulièrement mauvais avec votre code. –

+0

Ce que vous essayez d'accomplir n'est pas clair, il est donc difficile de recommander un meilleur moyen. Pourquoi attrapez-vous toutes les exceptions et les enveloppez-vous d'une exception personnalisée? Il semble que vous essayiez d'éviter toutes les exceptions vérifiées avec une exception non vérifiée. – WhiteFang34

Répondre

6

Juste une suggestion de base, mais vous pouvez factoriser cela en quelque chose comme un « modèle de commande. » Ce modèle vous permet d'encapsuler certaines fonctionnalités dans une classe qui implémente une méthode unique. La classe peut être instanciée et passée dans une autre classe pour être exécutée, et la classe d'exécuteur n'a pas besoin de savoir ou de se soucier de ce qu'elle fait, elle doit simplement appeler execute(). Si les actions nécessitent des arguments, les classes qui implémentent la commande peuvent inclure des champs/propriétés qui peuvent être définis dans le constructeur ou par des paramètres de propriété standard.

Faire une interface comme celui-ci (mon Java est rouillé, donc cela ne peut pas être 100% de syntaxe valide):

public interface Command 
{ 
    public void execute(); 
} 

public class ActionOne implements Command 
{ 
    public void execute() 
    { 
     // do actionOne... 
    } 
} 

public class ActionTwo implements Command 
{ 
    public void execute() 
    { 
     // do actionTwo... 
    } 
} 

// etc. for more actions 

Ensuite, créez la classe qui exécute l'action, et le code d'appel a juste besoin de passer dans la classe d'implémentation de commande correcte.

public class Executor 
{ 

    public void executeCommand(Command command) 
    { 
     try 
     { 
      // Put any boilerplate code here (logging, auditing, etc.) 
      command.execute(); 
     } 
     catch (Exception ex) 
     { 
      // Put general error handling code here. If you're just catching and rethrowing, consider not catching the Exception at this level. If it's a checked exception, add a throws clause to the method. 
      throw new CustomException(); 
     } 
    } 
} 
+0

J'apprécie votre suggestion, mais en utilisant Command Pattern semble augmenter le nombre de mes classes. J'envisage d'utiliser class Method pour invoquer dynamiquement. – Genzer

+2

Pourquoi vous souciez-vous d'augmenter le nombre de classes? 10 petites classes ciblées valent mieux qu'une grande classe qui doit faire 10 choses différentes. Je voudrais également éviter toute réflexion à moins que vous ayez absolument à suivre cette route. Votre code peut être exprimé de manière beaucoup plus concise en utilisant certaines interfaces et classes de base. –

+0

J'essaie de refactoriser une classe avec le même problème. D'autres suggestions si ma classe a ~ 100 méthodes? La seule chose à laquelle je peux penser est de créer un nouveau paquet pour les classes Action. – TheAmpersand

1

Oui, vous pouvez toujours refactoriser le code. Le seul problème est de savoir si vous allez refactoriser pour le rendre meilleur ou pire. Les indices que ce code est impair, est un bon indice qu'il peut être fait beaucoup mieux.

Cela ressemble à un bon candidat pour polymorphisim. Au lieu de cinq méthodes différentes, essayez cinq classes différentes avec une méthode partagée. L'interface va lier tout cela ensemble.

public interface DoIt { 
    public void doIt(); 
} 

public class One implements DoIt { 
    public void doIt() { 
    // code which was previously in getHelper.doActionOne(); 
    } 
} 

public class Two implements DoIt { 
    public void doIt() { 
    // code which was previously in getHelper.doActionTwo(); 
    } 
} 

... 

public class Five implements DoIt { 
    public void doIt() { 
    // code which was previously in getHelper.doActionFive(); 
    } 
} 

Maintenant, la seule chose est de créer la bonne classe pour la situation et appeler sa méthode doIt().

0

Cette fonctionnalité est fournie par le Spring Framework avec beaucoup d'autres. Tout d'abord, il dispose d'un HibernateTemplate spécifique qui mappe chaque exception spécifique à Hibernate à une exception Spring non liée liée. Deuxièmement, il fournit un service AOP pour traduire les exceptions au niveau de la méthode afin que vous puissiez spécifier les mappages une seule fois et les appliquer uniformément sur plusieurs services.

Même si je n'utiliserais pas Spring pour cette seule fonctionnalité, elle présente d'énormes avantages pour les applications de construction et je continue de l'utiliser depuis de nombreuses années.

Questions connexes