87 votes

Une différence de style : IDictionary vs Dictionary

J'ai un ami qui se lance dans le développement .NET après avoir développé en Java pendant des années et, après avoir examiné certains de ses codes, j'ai remarqué qu'il fait assez souvent ce qui suit :

IDictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>();

Il déclare que le dictionnaire est l'interface plutôt que la classe. Typiquement, je ferais ce qui suit :

Dictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>();

Je n'utiliserais l'interface IDictionary que lorsqu'elle est nécessaire (par exemple, pour passer le dictionnaire à une méthode qui accepte une interface IDictionary).

Ma question est la suivante : sa façon de faire a-t-elle des mérites ? S'agit-il d'une pratique courante en Java ?

12 votes

Pour les variables locales, il n'y a vraiment aucun intérêt.

0 votes

6 votes

Une bonne pratique MAIS Attention au coût de la performance : nimaara.com/2016/03/06/beware-of-the-idictionary-tkey-tvalue

80voto

Chris Points 995

Si IDictionary est un type "plus générique" que Dictionary, il est logique d'utiliser le type le plus générique dans la déclaration des variables. De cette façon, vous n'avez pas à vous soucier autant de la classe d'implémentation affectée à la variable et vous pouvez facilement changer le type à l'avenir sans avoir à modifier une grande partie du code suivant. Par exemple, en Java, il est souvent considéré comme préférable de faire

List<Integer> intList=new LinkedList<Integer>();

qu'il ne l'est de faire

LinkedList<Integer> intList=new LinkedList<Integer>();

De cette façon, je suis sûr que tout le code suivant traite la liste comme une liste et non comme une liste chaînée, ce qui facilitera à l'avenir le remplacement de la liste chaînée par un vecteur ou toute autre classe qui implémente la liste. Je dirais que ceci est commun à Java et à la bonne programmation en général.

27 votes

+1, mais vous devriez peut-être utiliser le mot "général" plutôt que "générique", qui a déjà un tas de sens :)

28voto

Justin Niessner Points 144953

Cette pratique ne se limite pas à Java.

Il est souvent utilisé dans .NET également lorsque vous voulez découpler l'instance de l'objet de la classe que vous utilisez. Si vous utilisez l'interface plutôt que la classe, vous pouvez changer le type de support chaque fois que nécessaire sans casser le reste de votre code.

Vous verrez également que cette pratique est très utilisée pour traiter les conteneurs IoC et l'instanciation à l'aide du modèle Factory.

1 votes

Mais vous perdez toutes les fonctionnalités que Dictionary pourrait fournir et qui ne sont pas dans IDictionary.

10 votes

Mais si vous êtes capable d'utiliser IDictionary à la place... vous n'utilisez pas la fonctionnalité pour commencer.

1 votes

Mais si vous n'avez besoin que de la fonctionnalité d'IDictionary... Il est plus facile de changer IDictionary en Dictionary que l'inverse :)

16voto

Votre ami suit le principe très utile :

"S'abstraire des détails de mise en œuvre"

6 votes

Mais il s'agit de détails de mise en œuvre. Nous ne créons pas une interface vers une classe - nous déclarons simplement une variable locale.

8 votes

Pas vraiment, IMHO. Si les membres de l'interface sont suffisants pour vous, je vous recommande vraiment de vous en tenir à l'interface. Rendez votre code aussi général que possible.

8voto

OscarRyz Points 82553

Vous devez toujours essayer de programmer en fonction de l'interface plutôt que de la classe concrète.

En Java ou tout autre langage de programmation orienté objet.

Dans le monde .NET, il est courant d'utiliser un I pour indiquer que c'est une interface que vous utilisez. Je pense que c'est plus courant parce qu'en C# ils n'ont pas de implements y extends pour faire référence à l'héritage des classes et des interfaces.

Je pense que le petit-lait ferait l'affaire

 class MyClass:ISome,Other,IMore 
 { 
 }

Et vous pouvez dire ISome un IMore sont des interfaces tandis que Other est une classe

En Java, il n'y a pas besoin d'une telle chose.

 class MyClass extends Other implements Some, More {
 }

Le concept reste valable, vous devez essayer de coder en fonction de l'interface.

3 votes

Je ne pense pas que sa question portait sur le fonctionnement des interfaces ou sur la raison pour laquelle elles commencent par I. De plus, les classes de base doivent être déclarées avant les interfaces. Donc, public class MyClass : BaseClass, IFirstInterface, ISecondInterface serait correcte. Il n'y a rien de spécial en soi à propos de I au début d'une interface. Le compilateur ne le traite pas différemment. C'est un marqueur pour les autres programmeurs. Vous pourriez nommer vos interfaces sans eux mais les autres programmeurs vous détesteraient probablement.

5voto

Gergely Orosz Points 4447

D'après ce que j'ai vu, les développeurs Java ont tendance à utiliser l'abstraction (et les modèles de conception) plus souvent que les développeurs .NET. Ceci semble en être un autre exemple : pourquoi déclarer la classe concrète alors qu'il ne travaillera essentiellement qu'avec les membres de l'interface ?

0 votes

J'étais avec toi jusqu'à la deuxième phrase. Comment faire autrement pour obtenir une référence à un implémenteur d'interface ? Vous devez instancier quelque chose qui l'implémente. new IDictionary<string, double>() ne fonctionnerait pas, et n'a aucun sens de toute façon.

0 votes

Je ne comprends pas vraiment... ce que je voulais dire, c'est que ceux qui utilisent le membre dictionnaire ne voudront utiliser que les capacités IDictionary. Évidemment, vous devez instancier quelque chose, mais si vous utilisez ce modèle, les codes suivants auront la même signification pour tous ceux qui utilisent la classe : IDictionary<T1, T2> dictionary = new Dictionary<T1, T2>() ; et IDictionary<T1, T2> dictionary = new ConcurrentDictionary<T1, T2>() ; Si vous n'utilisez pas les membres spécifiques de Dictionary ou ConcreteDictionary, il est logique de ne pas les déclarer comme type de variable de classe, en ajoutant une couche d'abstraction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X