2015-10-06 1 views
0

Je suis en train de refactoriser certaines parties de mon code, l'une d'entre elles a une fonction de rappel. Je ne suis pas vraiment sûr de la pertinence du rappel, car il introduit un couplage étroit.Rappel et couplage serré

Permettez-moi de vous donner un exemple:

public class SimpleExample { 
OtherClass oc; 
Callback callback; 
... 

public void register(Callback c) { 
    this.callback = c; 
} 

public void doStuff() { 
    callback.push(oc); 
} 
... 

} 

L'interface:

public interface Callback { 
public void push(OtherClass oc); 
} 

La mise en œuvre de l'interface:

public CallbackImpl implements Callback { 
HashMap<OtherClass, String> map; 
... 
public void push(OtherClass oc) { 
    String s = map.get(oc); 
    System.out.println(s); 
} 
... 
} 

Le principal problème que je vois est que mon interface utilisez OtherClass en tant que paramètre de fonction. Il est important de mentionner que OtherClass n'est pas une interface. Donc, ma première signification était de refactoriser cette classe avec une interface. Est-ce un bon choix ?

+0

Cela dépend de la visibilité de 'OtherClass'. S'il s'agissait d'un objet très public (par exemple 'String'), il est inutile de le remplacer. Si vous pensez qu'il peut y avoir plusieurs implémentations de 'OtherClass' que le remplacement est un bon choix, sinon tout consommateur de' Callback' nécessite une instance de 'OtherClass'. – hotzst

Répondre

1

Oui, c'est probablement une bonne idée. Votre rappel ne doit pas se préoccuper de l'implémentation exacte de l'objet qui lui est passé. Les interfaces facilitent également les simulations de tests.

L'exception que je ferais est pour les petites classes immuables, qui sont analogues aux structs dans d'autres langages. Pour ceux-ci, l'implémentation, le contenu et l'interface sont plus ou moins identiques.

Y a-t-il beaucoup d'intérêt à avoir une interface pour cela?

public final class Point { 

    private final int x; 
    private final int y; 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    Point (final int x, final int y) { 
     super(); 

     this.x = x; 
     this.y = y; 
    } 

    // hashCode etc... 
} 

Vous devriez également envisager d'utiliser les interfaces fonctionnelles intégrées pour votre rappel. Jetez un oeil à Consumer<T>.

+0

Merci, j'aime ton exemple avec Point car cela signifie qu'il n'est pas obligatoire de mettre une interface partout. Pour l'interface fonctionnelle, je vais regarder de plus près, mais je ne suis pas sûr si cela aiderait. – Poke

0

Oui, c'est une bonne idée, car alors vous rompez le couplage entre votre callback et la bibliothèque qui l'utilise, et cela vous permettra d'utiliser le callback depuis d'autres endroits et aussi de tester le callback seul sans avoir besoin de l'autre bibliothèque