2010-07-01 7 views
9

Dans le projet sur lequel je travaille, j'ai remarqué que pour chaque classe d'entité il y a une interface. Il semble que la motivation originale était de n'exposer que des interfaces à d'autres projets/solutions. Je trouve cela complètement inutile, et je ne vois pas l'intérêt de créer une interface pour chaque classe. Au fait, ces classes n'ont pas de méthodes juste des propriétés et elles n'implémentent pas la même interface.C# - L'ajout systématique d'une interface est-il une bonne pratique?

Je me trompe? Ou est-ce une bonne pratique?

Thx

+2

Avez-vous des exemples? Je vous recommande de lire cette réponse: http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface/384067#384067 –

+0

S'il s'agit de classes COM, c'est normal (lire: sorte de requis). –

+0

Possible duplicate of [Est-ce la meilleure pratique pour extraire une interface pour chaque classe?] (Http://stackoverflow.com/questions/3036749/is-it-the-best-practice-to-extract-an-interface- pour tous les cours) – DavidRR

Répondre

6

La configuration peut être plus complexe que celle décrite ici, ce qui justifie la surcharge des interfaces. Généralement, ils sont très utiles pour l'injection de dépendances et la séparation globale des préoccupations, tests unitaires et moqueurs, etc. Il est tout à fait possible qu'ils ne soient pas utilisés à cette fin (ou tout autre but constructif, vraiment) dans votre environnement. .

Est-ce du code généré ou ont-ils été créés manuellement? Si le premier, je soupçonne que l'outil les générant le fait pour se préparer à une telle utilisation si le développeur était si enclin. Si ce dernier, peut-être le concepteur original avait quelque chose en tête?

Pour mes propres «meilleures pratiques», je fais presque toujours du développement piloté par interface. C'est généralement une bonne pratique de séparer les préoccupations les unes des autres et d'utiliser les interfaces comme des contrats entre elles.

+0

Je préfère YAGNI, mais je pense que vos raisons possibles pour les interfaces dans ce projet particulier sont sur place. – Marc

+2

En général, je suis d'accord avec YAGNI. En tant que développeur d'entreprise, mon objectif est toujours «bon pour l'entreprise» plutôt que «bon pour le code». Bien sûr, l'entreprise ne comprend pas toujours que les deux sont souvent un seul et même :) – David

7

J'ai tendance à créer une interface pour presque toutes les classes principalement en raison de tests unitaires - si vous utilisez l'injection de dépendance et que vous voulez test unitaire une classe qui dépend de la classe en question, que la méthode standard est se moquer d'une instance de la classe en question (en utilisant l'un des cadres moqueurs, par exemple Rhino-Mocks). Cependant, pratiquement cela n'est possible que pour des interfaces, pas pour des implémentations concrètes (oui, théoriquement, on peut se moquer d'une classe concrète, mais il y a beaucoup de limites douloureuses).

4

C'est utile pour les tests. Une méthode peut prendre un paramètre de type ISomething, et peut être soit SqlSomething ou XmlSomething, où ISomething est l'interface, et SqlSomething et XmlSomething sont des classes qui implémentent l'interface, selon que vous faites des tests (vous passez XmlSomething dans ce cas) ou en cours d'exécution de l'application (SqlSomething). Aussi, lors de la construction d'un projet universel, qui peut fonctionner sur n'importe quelle base de données, mais n'utilise pas d'outil ORM comme LINQ (peut-être parce que le moteur de base de données ne supporte pas LINQ to SQL). vous utilisez dans l'application. Plus tard, les développeurs vont implémenter les interfaces pour travailler avec la base de données, créer la classe MySQLProductRepository, la classe PostgreSQLProductRepository, qui héritent toutes deux de la même interface, mais ont des fonctionnalités différentes.

Dans le code de l'application, toute méthode prend un paramètre un objet de référentiel de type IProductRepository, qui peut être n'importe quoi.

1

Si ces classes ont seulement des propriétés, alors les interfaces n'ajoutent pas beaucoup de valeur, car aucun comportement n'est abstrait.

Les interfaces peuvent être utiles pour l'abstraction, de sorte que la mise en œuvre peut être raillée dans les tests unitaires. Mais dans une application bien conçue, les entités métier/domaine doivent avoir très peu de raisons d'être moquées. D'autre part, les services métier/domaine sont un excellent candidat pour l'abstraction d'interface.

J'ai créé des interfaces pour mes entités une fois, et cela n'a ajouté aucune valeur. Cela m'a seulement fait réaliser que mon design était mauvais.

1

IMHO il semble que l'écriture d'interfaces sans raison est inutile. Vous ne pouvez pas être totalement fermé d'esprit, mais en général, faire des choses qui ne sont pas immédiatement utiles ont tendance à s'accumuler comme des déchets.

Le concept agile de Son soit ajouter de la valeur ou prendre de la valeur vient à l'esprit. Que se passe-t-il lorsque vous les supprimez? Si rien alors ... qu'est-ce qu'ils sont là pour?

En note. Interfaces sont extrêmement utiles pour Rhino Mocks, l'injection de dépendance et ainsi de suite ...

5

Exposant interfaces publiquement a la valeur dans la création d'une architecture faiblement couplée, axée sur le comportement. Créer une interface pour chaque classe - surtout si l'interface expose juste toutes les méthodes publiques de la classe dans une seule interface - est une mauvaise implémentation du concept, et (selon mon expérience) conduit à un code plus complexe et aucune amélioration en architecture.

+0

+1 - Totalement cela. Les interfaces sont un outil. Comme tout outil, ils ont de bonnes utilisations et des utilisations moins bonnes. Et cet exemple ne sonne pas bien. – GalacticCowboy

+0

Ce n'est pas si grave si l'interface existe avant que la classe ne le fasse - mais simplement créer 'IFoo' pour chaque classe' Foo' n'est pas très utile. – kyoryu

0

Pour les tests unitaires, il s'agit soit d'interfaces partout, soit de méthodes virtuelles partout.

Parfois, je manquez Java :)

1

Il semble être une interface est supérieure à une classe de base abstraite surtout si/quand il est nécessaire d'avoir une classe qui implémente l'interface, mais hérite d'une autre classe de base. L'héritage multiple n'est pas autorisé, mais plusieurs implémentations d'interface le sont. La mise en garde principale que je vois avec l'utilisation d'interfaces plutôt que de classes abstraites (au-delà du code source supplémentaire requis) est que tout changement dans une interface nécessite la recompilation de tout code qui utilise cette interface. En revanche, l'ajout de membres publics à une classe de base requiert généralement uniquement la recompilation de la classe de base elle-même. (*)

(*) En raison de la manière dont les méthodes d'extension sont gérées, l'ajout de membres à une classe ne nécessite pas de "requérir" recompiler le code qui utilise cette classe, mais peut faire en sorte que le code qui utilise les méthodes d'extension de la classe change de signification la fois suivante (le code utilisant la méthode d'extension) est recompilé.

1

Il n'y a aucun moyen de prédire l'avenir et de voir si vous allez avoir besoin de programmer par rapport à une interface en cours de route. Mais si vous décidez plus tard de tout utiliser une interface et, disons, une usine pour créer des instances de types inconnus (tout type qui implémente l'interface), alors il est plus rapide de restreindre la programmation à une interface et une usine Pour remplacer les références à MyImpl par des références à IMyInterface plus tard, etc.

Ainsi, lorsque vous écrivez un nouveau logiciel, il est judicieux de programmer la programmation par rapport à une interface ou une implémentation, sauf si vous savez ce qui risque de se produire. ce genre de logiciel basé sur des expériences précédentes. Habituellement, je le garde «en flux» pendant un certain temps, que j'aie ou non une interface, une classe de base, ou les deux, et même si la classe de base est abstraite (c'est généralement le cas). Je vais travailler sur un projet (habituellement une solution Visual Studio avec environ 3 à 10 projets) pendant un moment (quelques jours, peut-être) avant de refactoriser et/ou de demander un deuxième avis. Une fois qu'une décision finale est atteinte et que le code est refactorisé et testé, je dis à mes amis développeurs qu'il est prêt à l'emploi.

Questions connexes