11
votes

Bon cas pour les interfaces

Je travaille dans une entreprise où certains nécessitent une justification de l'utilisation d'une interface dans notre code (Visual Studio C # 3.5).

J'aimerais demander un raisonnement à repasser de fer que des interfaces sont requises pour. (Mon objectif est de prouver que les interfaces sont une partie normale de la programmation.)

Je n'ai pas besoin de convaincre, j'ai juste besoin d'un bon argument à utiliser dans le convaincre des autres.

Le type d'argument que je cherche est basé sur des faits, non basé sur la comparaison (c.-à-d. "parce que la bibliothèque .NET les utilise" est basée sur la comparaison.)

L'argument contre eux est donc: si une classe est correctement configurée (avec ses membres publics et privés), une interface n'est que des frais généraux supplémentaires car ceux qui utilisent la classe sont limités aux membres du public. Si vous devez avoir une interface implémentée par plus de 1 classe, il suffit de configurer l'héritage / polymorphisme.


5 commentaires

Je ne comprends pas l'argument contre ...


Si vous devez expliquer à votre équipe, pourquoi les interfaces sont une bonne norme de programmation, vous devriez trouver un nouvel emploi.


Je suis d'accord avec le nouveau commentaire d'emploi.


Merci pour toutes les grandes réponses!


"Pourquoi utiliser des fonctions lorsque GOTO fonctionne bien" c'est fondamentalement le même argument.


17 Réponses :


27
votes

Découplage de code. En programmant pour les interfaces, vous découplez le code à l'aide de l'interface du code implémentant l'interface. Cela vous permet de modifier la mise en œuvre sans avoir à refacturer tout le code en l'utilisant. Cela fonctionne conjointement avec l'héritage / polymorphisme, vous permettant d'utiliser l'une quelconque de plusieurs implémentations possibles de manière interchangeable.

Des tests moqueurs et unités. Les cadres moqueurs sont faciles à utiliser lorsque les méthodes sont virtuelles, que vous obtenez par défaut avec des interfaces. C'est en fait la principale raison pour laquelle je crée des interfaces.

Définition du comportement qui peut s'appliquer à de nombreuses classes différentes qui leur permet d'être utilisées de manière interchangeable, même lorsqu'il n'y a pas de relation (autre que le comportement défini) entre les classes. Par exemple, un cheval et une classe de vélo peuvent tous deux avoir une méthode de conduite. Vous pouvez définir une interface idiable qui définit le comportement de trajet et toute classe qui utilise ce comportement peut utiliser un objet de cheval ou de vélo sans forcer un héritage non naturel entre eux.


4 commentaires

J'allais écrire quelque chose comme ça, mais je ne suis pas assez éloquent. Donc, je laisse quelqu'un de mieux le faire. Le découplage est la programmation la plus importante en partie qu'elle fournit une flexibilité, une facilité de gestion et une réévaluabilité.


Comme un addendum au commentaire cheval / vélo, la bonne chose à propos des interfaces est de pouvoir généraliser les opérations de votre classe sans limiter votre héritage: Stackoverflow.com/questions/558152/...


Si un changement de mise en œuvre impliquait une nouvelle signature de méthode, l'ajout d'une telle méthode enfreint tous les clients à l'aide de l'interface. Quel genre de découplage est-ce? Devrions-nous visons une combinaison d'interface et de classe abstraite?


Bien dans ce cas, vous ne modifiez pas la mise en œuvre, mais le contrat. Vous ne devriez pas vous attendre à être découplé du contrat, juste la mise en œuvre concrète du contrat.



1
votes

Si votre magasin effectue des tests automatisés, les interfaces sont une excellente arnaque à une injection de dépendance et de la possibilité de tester une unité de logiciels isolément.


0 commentaires

2
votes
  • Développement axé sur le test
  • Test de l'unité

    sans interfaces produisant du code découplé serait une douleur. La meilleure pratique consiste à coder une interface plutôt qu'à une mise en œuvre concrète. Les interfaces semblent des ordures au début, mais une fois que vous avez découvert les avantages, vous les utiliserez toujours.


0 commentaires

6
votes

Pour activer les tests d'unités de la classe.

Pour suivre efficacement les dépendances (si l'interface n'est pas vérifiée et touchée, seule la sémantique de la classe peut éventuellement avoir changé).

Parce qu'il n'y a pas de frais généraux d'exécution.

Pour activer l'injection de dépendance.

... et peut-être parce que c'est friggin '2009, pas les années 70 et les concepteurs de langue moderne ont une idée de ce qu'ils font?

Ce n'est pas que les interfaces doivent être jetées à chaque interface de classe: juste ceux qui sont au centre du système et qui sont susceptibles de connaître un changement important et / ou une extension.


0 commentaires

2
votes
  • Vous pouvez implémenter plusieurs interfaces. Vous ne pouvez pas hériter de plusieurs classes.
  • .. c'est tout. Les autres que d'autres font sur le découplage du code et le développement axé sur les tests ne se rendent pas au cœur de la matière, car vous pouvez aussi faire ces choses avec des classes abstraites.

3 commentaires

Pas nécessairement, les classes abstraites doivent être utilisées lorsqu'il y a une logique commune à partager. Je peux avoir 2 classes qui implémentent la même interface mais qui ont une structure complètement différente ensemble.


Pourquoi se soucier d'une classe abstraite si vous allez seulement remplacer la mise en œuvre de la base? Ainsi, les interfaces sont meilleures pour les tests unitaires. Les classes abstraites ont leur place cependant.


Je conviens que les classes abstraites manifestement devraient fournir une certaine implémentation, sinon elles devraient être des interfaces. Mais je réponds directement à la question.



10
votes

En plus des choses expliquées dans d'autres réponses, interfaces vous permet de simuler héritage multiple in .NET qui n'a pas non plus permis.

hélas comme quelqu'un a dit

La technologie est dominée par deux types de personnes: ceux qui comprennent ce qu'ils ne gèrent pas, et ceux qui gèrent ce qu'ils ne comprennent pas.


2 commentaires

C'est un très bon point. Parce que .NET ne prend pas en charge plusieurs héritages, l'utilisation d'interfaces est à peu près obligatoire.


Meta-Knight: C'est la ligne de fête, mais je ne suis pas sûr de le croire. Vous ne pouvez pas simplement structurer les choses différemment de ne pas nécessiter de multiples superclasses dans une sous-classe? Diriez-vous également que "parce que .NET ne prend pas en charge plusieurs envois, écrire votre propre répartiteur est à peu près obligatoire"? Il y a toujours des systèmes d'objets plus puissants, mais vous n'avez pas toujours à imiter toutes leurs caractéristiques pour obtenir quelque chose.



2
votes

Interfaces vous permet de déclarer un concept pouvant être partagé parmi de nombreux types ( ienumerable ) tout en permettant à chacun de ces types d'avoir sa propre hiérarchie héritabilité.

Dans ce cas, ce que nous disons, c'est "Cette chose peut être énumérée, mais ce n'est pas sa seule caractéristique déterminante".

Les interfaces vous permettent de prendre le montant minimum de décisions nécessaires lors de la définition des capacités de la mise en œuvre. Lorsque vous créez une classe au lieu d'une interface, vous avez déjà déclaré que votre concept est uniquement de classe et non utilisable pour les structures. Vous faites également d'autres décisions lorsque vous déclarez des membres dans une classe, tels que la visibilité et la virtualité.

Par exemple, vous pouvez faire une classe abstraite avec tous les membres abstraits publics, et c'est assez proche d'une interface, mais vous avez déclaré que le concept aussi exclu dans toutes les classes d'enfants, alors que vous n'auriez pas obligé d'avoir fait que décision si vous avez utilisé une interface.

Ils effectuent également des tests unitaires plus facilement, mais je ne crois pas que ce soit un argument puissant, car vous pouvez créer un système sans tests d'unité (non recommandés).


0 commentaires

4
votes

interfaces et classes abstraites modélisent différentes choses. Vous dérivez d'une classe lorsque vous avez une relation ISA afin que la classe de base modélise quelque chose de concret. Vous implémentez une interface lorsque votre classe peut effectuer un ensemble de tâches spécifique.

Pensez à quelque chose qui est sérialisable, il n'a pas vraiment de sens (d'un point de vue de conception / modélisation) pour avoir une classe de base appelée sérialisisable car il n'a pas de sens de dire quelque chose d'Isa sérialisable. Avoir quelque chose à mettre en œuvre une interface sérialisable a plus de sens comme disant «c'est quelque chose que la classe peut faire, pas ce que la classe est '


0 commentaires

0
votes

Je ne comprends pas comment ses frais généraux supplémentaires.

interfaces fournissent une flexibilité, un code gérable et une réutilisabilité. Codage à une interface dont vous n'avez pas besoin de vous inquiéter du code de mise en œuvre concret ou de la logique de la certaine classe que vous utilisez. Vous attendez juste un résultat. De nombreuses classes ont une implémentation différente pour la même chose (StreamWriter, StringWriter, XMLWriter). Vous n'avez pas besoin de vous inquiéter de la manière dont ils implémentent l'écriture, il vous suffit de l'appeler.


3 commentaires

Il est surcharge supplémentaire si vous créez vos propres interfaces, car vous devez créer et maintenir plus de code. Pour chaque méthode, vous souhaitez tirer dans l'interface, vous devez dupliquer la signature de la méthode. Ensuite, chaque fois que vous devez modifier la signature de la méthode, vous devrez le changer au moins deux places.


Vous soutenez les deux arguments ici. Streamwriter et StringWriter sont des implémentations d'une classe abstraite (Textwriter); Xmlwriter n'est pas liée à l'exception de l'objet et de l'Idisposable.


Oui bon point, je ne pensais pas à la façon dont .Net le met en œuvre réellement. J'essayais de penser à un rapide exemple de classes qui partagent une fonctionnalité (écrire) mais les implémenter différemment ..



1
votes

Le problème avec l'argument de l'héritage est que vous aurez un gigantesque classe de Dieu ou une hiérarchie si profonde, cela fera tourner votre tête. En plus de cela, vous vous retrouverez avec des méthodes sur une classe dont vous n'avez pas besoin ou que vous n'avez aucun sens.

Je vois beaucoup de "non-héritage multiple" et que c'est vrai, cela ne sera probablement pas sous tension de votre équipe, car vous pouvez avoir plusieurs niveaux d'héritage pour obtenir ce qu'ils voudraient.

Une implémentation isisposable vient à l'esprit. Votre équipe mettrait une méthode de disposition sur la classe d'objet et la laisser se propager à travers le système, que cela soit ou non valable pour un objet ou non.


0 commentaires

19
votes

L'argument contre eux est donc: si une classe est correctement configurée (avec son membres publics et privés) alors un L'interface est juste des frais généraux supplémentaires parce que ceux qui utilisent la classe sont restreint aux membres du public. Si tu besoin d'avoir une interface qui est mis en œuvre par plus de 1 classe alors Il suffit de configurer l'héritage / polymorphisme. P>

Considérez le code suivant: p>

interface ICrushable
{
  void Crush();
}

public class Vehicle
{
}

public class Animal
{
}

public class Car : Vehicle, ICrushable
{
  public void Crush()
  {
     Console.WriteLine( "Crrrrrassssh" );
  }
}

public class Gorilla : Animal, ICrushable
{
  public void Crush()
  {
     Console.WriteLine( "Sqqqquuuuish" );
  }
}

0 commentaires

1
votes

Une interface déclare un contrat selon lequel tout objet la mettant en œuvre adhérera à. Cela permet de garantir la qualité de la qualité dans le code plus facile que d'essayer d'appliquer une structure écrite (non codate) ou verbale, le moment où une classe est décorée avec la référence de l'interface Les exigences / contrat sont clairs et le code ne compilera pas avant de mettre en œuvre la mise en œuvre. cette interface complètement et de type-coffre-fort.

Il existe de nombreuses autres raisons pour lesquelles utiliser des interfaces (répertoriées ici) mais ne résonnez probablement pas à la direction, ainsi qu'une bonne déclaration de «qualité» ancienne;)


0 commentaires

1
votes

Eh bien, ma 1ère réaction est que si vous devez expliquer pourquoi vous avez besoin d'interfaces, c'est une bataille en montée de toute façon :)

Cela étant dit, autre que toutes les raisons mentionnées ci-dessus, les interfaces sont la seule façon de programmer des couplies lâches, des architectures N-Ter dans lesquelles vous devez mettre à jour / remplacer des composants à la volée, etc. - dans l'expérience personnelle mais aussi Esoteric Un concept pour la tête de l'équipe d'architecture avec le résultat que nous vivions dans dll enfer - dans le monde .net non moins!


0 commentaires

1
votes

S'il vous plaît, veuillez me pardonner pour le pseudo code à l'avance!

Lisez sur des principes solides. Les principes solides ont quelques raisons pour utiliser des interfaces. Les interfaces vous permettent de découpler vos dépendances sur la mise en œuvre. Vous pouvez également prendre une étape supplémentaire en utilisant un outil tel que StructureMap pour effectuer réellement le couplage de l'accouplement. P>

où vous pourriez être utilisé pour P>

[PluginFamily("Default")]
public interface IAnotherObject
{
    ...
}

[PluginFamily("Default")]
public interface ICallingObject
{
    ...
}

[Pluggable("Default")]
public class AnotherObject : IAnotherObject
{
    private IWidget _widget;
    public AnotherObject(IWidget widget)
    {
        _widget = widget;
    }

    public void SomeMethod()
    {
        //..do something with _widget
    }
}

[Pluggable("Default")]
public class CallingObject : ICallingObject
{
    public void AnotherMethod()
    {
        ObjectFactory.GetInstance<IAnotherObject>().SomeMethod();
    }
}


0 commentaires

1
votes

appologies car cela ne répond pas à votre question concernant un cas pour les interfaces.

Cependant, je suggère d'obtenir la personne en question à lire ..

Tête Premier modèle de conception

- Lee


0 commentaires

3
votes

Les interfaces ne sont pas "requises pour" du tout, c'est une décision de conception. Je pense que vous devez vous convaincre, pourquoi, au cas par cas, il est bénéfique d'utiliser une interface, car il y a une surcharge dans l'ajout d'une interface. D'autre part, pour contrer l'argument contre les interfaces parce que vous pouvez simplement utiliser l'héritage: l'héritage a son tirage, l'un d'entre eux est celui-là - au moins en C # et Java - vous ne pouvez utiliser que l'héritage une fois (héritage unique); Mais le second - et peut-être plus important - est-ce que l'héritage vous oblige à comprendre le fonctionnement de la classe mère non seulement, mais toutes les classes des ancêtres, ce qui rend la prolongation plus difficile mais aussi plus fragile, car un changement de la classe mère ' La mise en œuvre pourrait facilement casser les sous-classes. C'est le creux de la "composition sur l'héritage" argument selon lequel le livre Gof nous a appris.


1 commentaires

3
votes

Vous avez reçu un ensemble de directives que vos patrons ont pensé approprié pour votre lieu de travail et votre domaine problématique. Donc, pour être persuasif sur la modification de ces directives, il ne s'agit pas de prouver que les interfaces sont une bonne chose en général, il s'agit de prouver que vous en avez besoin sur votre lieu de travail.

Comment prouvez-vous que vous avez besoin d'interfaces dans le code que vous écrivez sur votre lieu de travail? En trouvant une place dans votre codeBase actuel (pas dans certains codes du produit de quelqu'un d'autre, et certainement pas dans un exemple de jouet sur le canard mettant en œuvre la méthode Makenoise en Ianimal) où une solution à base d'interface est meilleure qu'une solution basée sur l'interface. Montrez à vos patrons le problème que vous rencontrez et demandez s'il est logique de modifier les directives pour accueillir des situations comme celle-ci. C'est un moment enseignant où tout le monde examine les mêmes faits au lieu de vous frapper sur la tête avec des généralités et des spéculations.

La ligne directrice semble être motivée par une préoccupation quant à la préparation de la généralisation de surenromination et prématurée. Donc, si vous faites une dispute dans le sens de nous devrions avoir une interface ici au cas où nous devrions ... , c'est bien intentionné, mais pour vos patrons, il se détache de la même manière -Les cloches d'alarme qui ont motivé la ligne directrice en premier lieu.

Attendez qu'il y ait un bon cas d'objectif, cela va à la fois pour les techniques de programmation que vous utilisez dans le code de production et que vous commencez les arguments avec vos responsables.


0 commentaires