Program Club

스타일의 차이 : IDictionary vs Dictionary

proclub 2020. 11. 7. 10:41
반응형

스타일의 차이 : IDictionary vs Dictionary


오랫동안 Java로 개발 한 후 .NET 개발에 뛰어 드는 친구가 있는데, 그의 코드 중 일부를 살펴본 후 그가 다음 작업을 자주 수행하고 있음을 알았습니다.

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

그는 사전을 클래스가 아닌 인터페이스로 선언하고 있습니다. 일반적으로 다음을 수행합니다.

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

필요한 경우에만 IDictionary 인터페이스를 사용합니다 (예 : IDictionary 인터페이스를 허용하는 메서드에 사전을 전달하는 경우).

제 질문은 : 그의 일을하는 방식에 어떤 장점이 있습니까? 이것이 Java에서 일반적인 관행입니까?


IDictionary가 Dictionary보다 "더 일반적인"유형 인 경우 변수를 선언 할 때 더 일반적인 유형을 사용하는 것이 좋습니다. 이렇게하면 변수에 할당 된 구현 클래스에 대해 그다지 신경 쓰지 않아도되며 다음 코드를 많이 변경하지 않고도 나중에 유형을 쉽게 변경할 수 있습니다. 예를 들어, Java에서는 종종 더 나은 것으로 간주됩니다.

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

하는 것보다

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

이렇게하면 다음의 모든 코드가 목록을 LinkedList가 아닌 List로 취급하므로 나중에 LinkedList for Vector 또는 List를 구현하는 다른 클래스를 쉽게 전환 할 수 있습니다. 나는 이것이 Java와 일반적으로 좋은 프로그래밍에 공통적이라고 말하고 싶습니다.


이 관행은 Java에만 국한되지 않습니다.

사용중인 클래스에서 개체의 인스턴스를 분리하려는 경우에도 .NET에서도 자주 사용됩니다. 클래스 대신 인터페이스를 사용하는 경우 나머지 코드를 손상시키지 않고 필요할 때마다 지원 유형을 변경할 수 있습니다.

또한 팩토리 패턴을 사용하여 IoC 컨테이너 및 인스턴스화를 처리하는 데이 방법이 많이 사용되는 것을 볼 수 있습니다.


친구는 매우 유용한 원칙을 따르고 있습니다.

"구현 세부 사항에서 자신을 추상화"


이미 구현 세부 사항 인 지역 변수 및 개인 필드의 경우, 구체적인 클래스가 성능 향상을 제공하기 때문에 선언에 인터페이스보다 구체적인 유형을 사용하는 것이 좋습니다 (직접 발송이 가상 / 인터페이스 발송보다 빠름). JIT는 또한 로컬 구현 세부 사항에서 불필요하게 인터페이스 유형으로 캐스트하지 않는 경우 메소드를 더 쉽게 인라인 할 수 있습니다. 인터페이스를 반환하는 메서드에서 구체적인 유형의 인스턴스가 반환되는 경우 캐스트는 자동입니다.


항상 구체적인 클래스보다는 인터페이스에 프로그래밍을 시도해야합니다.

Java 또는 기타 객체 지향 프로그래밍 언어에서.

.NET 세계 I에서는를 사용하여 사용중인 인터페이스를 나타내는 것이 일반적 입니다. 나는 C #에서 그들은이 없기 때문에이 일반적인 생각 implementsextends인터페이스 상속 대 클래스를 참조 할 수 있습니다.

유청이

 class MyClass:ISome,Other,IMore 
 { 
 }

그리고 당신은 말할 수 ISomeIMore동안 인터페이스입니다 Other클래스입니다

Java에서는 그런 것이 필요하지 않습니다.

 class MyClass extends Other implements Some, More {
 }

개념은 여전히 ​​적용되며 인터페이스에 코딩을 시도해야합니다.


지금까지 Java 개발자는 .NET 개발자보다 추상화 (및 디자인 패턴)를 더 자주 사용하는 경향이 있습니다. 이것은 또 다른 예인 것 같습니다. 기본적으로 인터페이스 멤버로만 작업 할 때 구체적인 클래스를 선언하는 이유는 무엇입니까?


대부분의 경우 멤버가 어셈블리 외부에 있든 클래스 외부에 있든 관계없이 외부 코드에 멤버가 노출 될 때 사용되는 인터페이스 유형 (IDictionary)을 볼 수 있습니다. 일반적으로 대부분의 개발자는 인터페이스 유형을 사용하여 캡슐화 된 속성을 노출하는 동안 클래스 정의에 내부적으로 구체적인 유형을 사용합니다. 이러한 방식으로 구체적인 유형의 기능을 활용할 수 있지만 구체적인 유형을 변경하면 선언하는 클래스의 인터페이스를 변경할 필요가 없습니다.

공용 클래스 위젯
{
    private Dictionary <string, string> map = new Dictionary <string, string> ();
    공용 IDictionary <문자열, 문자열> 맵
    {
        get {return map; }
    }
}

나중에 다음이 될 수 있습니다.


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

공용 클래스 위젯
{
    private SpecialMap <string, string> map = new SpecialMap <string, string> ();
    공용 IDictionary <문자열, 문자열> 맵
    {
        get {return map; }
    }
}

위젯의 인터페이스를 변경하지 않고 이미 사용중인 다른 코드를 변경하지 않아도됩니다.


설명 된 상황에서 거의 모든 Java 개발자는 인터페이스를 사용하여 변수를 선언합니다. Java 컬렉션이 사용되는 방식은 아마도 가장 좋은 예 중 하나 일 것입니다.

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

많은 상황에서 느슨한 결합을 달성한다고 생각하십시오.


Java 컬렉션에는 다양한 구현이 포함됩니다. 따라서 사용하기가 훨씬 쉽습니다.

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

그런 다음 미래에 "myList"가 스레드로부터 안전해야한다는 것을 깨달았을 때이 한 줄을

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

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

Edit:

Failed to hit on one of my key points (just alluded to it with the getter/setters).

The above allows you to have:

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

And the client using this call need not worry about the underlying implementation. Using whatever object that conforms to the List interface that they may have.


Coming from a Java world, I agree that the "program to an interface" mantra is drilled into you. By programming to an interface, not an implementation, you make your methods more extensible to future needs.


I've found that for local variables it generally doesn't much matter whether you use the interface or the concrete class.

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

However, when declaring methods, class members, or interfaces, I think that it will save you quite a bit of headache to use the interface type up front, rather than coupling the public API to a specific class type.


Using interfaces means that "dictionary" in the following code might 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

It's best seen when you hide the construction of the object:

IDictionary dictionary = DictionaryFactory.getDictionary(...);

I've encountered the same situation with a Java developer. He instantiates collections AND objects to their interface in the same way. For instance,

IAccount account = new Account();

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


IDictionary is an interface and Dictionary is a class.

Dictionary implements IDictionary.

That means that this is possible to refer to Dictionary instance with/by IDictionary instance and invoke most of the Dictionary methods and properties through IDictionary instance.

This is very recommended to use interfaces as many as possible, because interfaces abstracts the modules and assemblies of the applications, allows polymorphism, which is both very common and useful in many situations and cases and allows replacing one module by another without touching the other modules.

Suppose that in the present, the programmer wrote:

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

And now dictionary invokes the methods and properties of Dictionary<string>.

In the future the databases has been grown up in size and we find out that Dictionary<string> is too slow, so we want to replace Dictionary<string> by RedBlackTree<string>, which is faster.

So all what is needed to be done is replacing the above instruction to:

IDictionary<string> dictionary = new RedBlackTree<string>();

Of course that if RedBlackTree implements IDictionary then all the code of the application compiles successfully and you have a newer version of your application, where the application now performs faster and more efficient than the previous version.

Without interfaces, this replacement would be more difficult to do and would require the programmers and developers to change more code that is potential to bugs.

참고URL : https://stackoverflow.com/questions/1595498/a-difference-in-style-idictionary-vs-dictionary

반응형