Style Difference: IDictionary vs Dictionary

I have a friend who just goes into .NET development after developing in Java for ages, and, looking at some of his code, I noticed that he quite often does the following:

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

It declares the dictionary as an interface, not a class. Normally I would do the following:

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

I used the IDictionary interface only when necessary (say, for example, to pass a dictionary to a method that accepts an IDictionary).

My question is: are there any merits in his way of doing something? Is this common practice in Java?

+53
java c # interface
20 Oct '09 at 15:31
source share
13 answers

If an IDictionary is a "more general" type than a dictionary, then it makes sense to use a more general type when declaring variables. This way, you don’t have to worry about the implementation class assigned to the variable, and you can easily change the type in the future without changing a lot of the following code. For example, in Java it is often considered better to do

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

how to do it

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

Thus, I am sure that all of the following code refers to a list as a list, not a LinkedList, which makes it easier in the future to turn off LinkedList for Vector or any other class that implements List. I would say that this is a common occurrence for Java and good programming in general.

+50
Oct 20 '09 at 15:35
source share

This practice is not limited to Java.

It is often used in .NET, when you want to separate an instance of an object from the class that you are using. If you use an interface, not a class, you can change the type of support if necessary, without breaking the rest of your code.

You will also see that this practice is heavily used when working with IoC and instanciation containers using the Factory pattern.

+24
Oct 20 '09 at 15:36
source share

Your friend adheres to a very useful principle:

"Give up implementation details"

+12
Oct 20 '09 at 15:38
source share

You should always try to program an interface, not a specific class.

In Java or any other object-oriented programming language.

In the .NET world, I is usually used to indicate that this is the interface you are using. I think this is more common because in C # they do not have implements and extends to reference inheritance of the class interface vs.

I think whey will print

  class MyClass:ISome,Other,IMore { } 

And you can say ISome a IMore interfaces, and Other - class

There is no need for such a thing in Java

  class MyClass extends Other implements Some, More { } 

The concept is still applied, you should try to execute code for the interface.

+7
Oct 20 '09 at 17:25
source share

As I have seen, Java developers are more likely to use abstractions (and design patterns) more often than .NET developers. This may seem like another example: why declare a specific class when it will work only with interface members?

+4
Oct 20 '09 at 15:36
source share

Most often, you see an interface type (IDictionary) used when a member is exposed to external code, whether it is outside the assembly or outside the class. Typically, most developers use a specific type inside the class to define the class, while they display the encapsulated property using the interface type. Thus, they can use the capabilities of a particular type, but if they change a specific type, the class declaration of the class does not need to be changed.

 public class Widget
 {
     private Dictionary <string, string> map = new Dictionary <string, string> ();
     public IDictionary <string, string> Map
     {
         get {return map;  }
     }
 }

later may become:

 class SpecialMap <TKey, TValue>: IDictionary <TKey, TValue> {...}

 public class Widget
 {
     private SpecialMap <string, string> map = new SpecialMap <string, string> ();
     public IDictionary <string, string> Map
     {
         get {return map;  }
     }
 }

without changing the Widget interface and the need to change other code that already uses it.

+4
Oct. 20 '09 at 17:11
source share

For local variables and private fields that are already implementation details, it is better to use specific types than interfaces for declarations, because specific classes offer improved performance (direct sending is faster than sending virtual / interfaces). JIT will also be able to more easily embed methods if you don't resort to unnecessarily resorting to interface types in local implementation details. If an instance of a particular type is returned from a method that returns an interface, casting is performed automatically.

+4
Oct. 20 '09 at 17:30
source share

In the situation described, almost every Java developer used an interface to declare a variable. The way you use Java collections is probably one of the best examples:

 Map map = new HashMap(); List list = new ArrayList(); 

Guess that it just performs loose grip in many situations.

+3
Oct 20 '09 at 15:42
source share

From the Java world, I agree that you have drilled the mantra "program for the interface." By programming an interface rather than an implementation, you make your methods more extensible for future needs.

+3
Oct. 20 '09 at 18:14
source share

I found that for local variables it doesn't really matter much whether you use an interface or a specific class.

Unlike class signatures or method signatures, there is very little refactoring effort if you decide to change types, as well as a variable that is visible outside its use site. In fact, when you use var to declare locals, you are not getting an interface type, but rather a class type (unless you explicitly applied to the interface).

However, when declaring methods, class members, or interfaces, I think that it will save you a little headache to use the type of interface in front, instead of associating the open API with a specific type of class.

+1
Oct 20 '09 at 15:37
source share

Using interfaces means that the "dictionary" in the following code can be any implementation of IDictionary.

 Dictionary1 dictionary = new Dictionary1(); dictionary.operation1(); // if operation1 is implemented only in Dictionary1() this will fail for every other implementation 

This is best seen when you hide the construction of an object:

 IDictionary dictionary = DictionaryFactory.getDictionary(...); 
+1
Oct. 20 '09 at 15:37
source share

Java Collections includes many implementations. Therefore, it’s much easier for me to use

 List<String> myList = new ArrayList<String>(); 

Then in the future, when I understand, I need the "myList" to be thread safe, just changing this single line to

 List<String> myList = new Vector<String>(); 

And do not change another line of code. This also includes getters / setters. If you look at the number of implementations of the Map, for example, you can imagine why this might be good practice. In other languages, where there is only a couple of implementations for something (sorry, not a big .NET guy), but in Objective-C there really is only NSDictionary and NSMutableDictionary. So it doesn’t make much sense.

Edit:

Failed to click on one of my key points (just referenced it using getter / seters).

The above allows you to:

 public void setMyList(List<String> myList) { this.myList = myList; } 

And the client using this call should not worry about the underlying implementation. Using any object that matches the List interface that they can have.

+1
Oct 20 '09 at 15:55
source share

I faced the same situation with a Java developer. It implements AND objects and their interface in the same way. For example,

 IAccount account = new Account(); 

Properties are always obtained / set as interfaces. This causes serialization problems, which is very well explained here

+1
Oct 20 '09 at 17:05
source share



All Articles