2010-12-05 3 views
0

Lors de la création d'une interface dont les méthodes sont appelées dans un ordre spécifique, cette dépendance est-elle une bonne pratique ou faut-il appliquer plus de modèles et de pratiques pour la "réparer" ou améliorer la situation?Pratique de la demande de dépendance lors de l'appel lors de la programmation des interfaces?

Les utilisateurs importants de certaines interfaces appellent des méthodes dans un ordre spécifique.

Il existe probablement de nombreux exemples variés. C'est la première qui vient à l'esprit:

Une interface de source de données dont l'auteur envisage que la méthode init soit toujours appelée en premier par n'importe quel appelant (ie pour se connecter à la source de données ou chercher des méta-informations préliminaires, etc.), avant que toutes les autres méthodes d'opération ne soient appelées. Toutefois, l'appelant peut choisir de ne pas appeler la méthode d'initialisation en premier.

En général, je me demande s'il existe de meilleurs moyens pour cette situation.

+1

Sûrement vous feriez toute cette initialisation sur le constructeur pour vous assurer que l'objet a été configuré avant d'interagir avec lui? – BeRecursive

+0

@BeRecursive: Bien que je répondrais normalement Oui, mais pas nécessairement le lien de commentaire ici: http://stackoverflow.com/questions/4361741/4361784#4361784 Intéressant –

Répondre

0

Je suis un peu confus. Les implémenteurs ne sont pas nécessairement des appelants ou des utilisateurs de l'interface. Dans votre exemple, les implémenteurs peuvent supposer qu'InitSelf est appelé avant toute autre chose, mais ils ne sont pas responsables de cela.

Je pense que nommer InitXXX est une bonne indication que c'est le cas.

Pour les dépendances plus impaires (pas Init, ce qui est très commun), il serait probablement préférable de ne pas avoir la dépendance.

Parfois, ce n'est pas possible, et si vous décidez qu'il n'est pas trop compliqué d'essayer de le réparer, il est courant de séparer en plusieurs interfaces auxquelles vous avez accès lorsque vous appelez les premières.

Un exemple courant est une interface de base de données. Vous appelez connect, il renvoie une connexion. Vous appelez createStatement sur la connexion, il renvoie une instruction. Vous appelez setParam sur l'instruction, vous appelez runStatement sur l'instruction, puis vous obtenez un résultat, etc.

+0

J'étais au milieu de la mise à jour de la question avec les informations de l'appelant tout en vous étiez en train d'écrire - jetez un autre coup d'œil et faites-moi savoir si c'est conceptuellement plus clair maintenant. THX. –

+0

Intéressant. Le concept de fournir de façon incrémentielle une interface à partir d'une autre est probablement le meilleur moyen de fournir une résolution pour de tels scénarios. J'aime ça. –

0

Toute initialisation doit être effectuée dans le constructeur. Les clients de l'interface DataAccess ne devraient pas avoir à se soucier des détails de construction.

+1

Bien que cela semble souvent le plus logique, cela peut aussi conduire à des constructeurs qui en font trop. http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/ –

+1

@Matt: Les méthodes d'initialisation font encore conceptuellement partie du "constructeur", même si elles ne le sont pas techniquement. Vous ne corrigez vraiment rien de cette façon. Ironiquement, la page que vous liez à même les états: "attention aux méthodes d'initialisation". –

+0

Bon point. Je suppose que l'utilisation de Spring a eu un peu d'effet sur mon état d'esprit puisqu'il permet de définir une méthode d'initialisation appelée automatiquement. –

1

Vous pourriez avoir les autres méthodes jeter une exception si l'objet n'est pas initialisé, ou vous pourriez opter pour une API plus stricte. Il serait plus compliqué à mettre en œuvre, mais par exemple, initself() peut retourner une interface contenant les opérations de données:

interface DataAccess { 
    DataOperations InitSelf(); 
} 

interface DataOperations { 
    T Op_GetDataValue<T>(int id); 

    ... 
} 

Ce serait sorte d'exiger du consommateur pour initialiser avant d'effectuer des opérations, mais il y aurait des moyens de contourner cela.

+0

Ceci est intéressant. Dans le passé, j'ai mis en œuvre des méthodes pour lancer une exception si l'initialisation n'a pas encore eu lieu; Cependant, je n'ai pas brisé l'interface comme le montre votre exemple. J'aime cet exemple. –

Questions connexes