클래스를 만들고 객체를 반환하는 대신 여러 항목을 반환하려는 경우 공용 메서드에서 해시 테이블을 반환 할 때의 디자인 문제는 무엇입니까?
문제가 있다면 어떤 상황에서 그렇게하는 것이 합리적입니까?
이 질문에 대한 답은 언어가 동적인지 아닌지에 따라 어떻게 변합니까?
편집 : 이것은 키가 일정하고 데이터가 아닌 코드의 일부임을 분명히하기 위해입니다. 우리가 일반적으로 클래스를 만드는 것. 문제는 클래스를 만드는 것이 실제로 올바른 선택 인 경우 대신 해시 테이블을 사용하는 것이 왜 잘못된 것입니까?
답변
이름 / 값 쌍으로 임의의 수의 값을 보유하는 해시 테이블보다 더 잘 정의 된 클래스를 리턴 유형으로 사용하십시오.
-
가장 중요한 첫 번째 요점은 유지 관리 성입니다. 새로운 프로그래머는 코드를 살펴보면 메소드가 리턴하는 값이 무엇인지 말할 수 없습니다. 새로운 사람이 코드를보고이를 이해하지 못하면 코드가 유용하지 않으며 누군가가 해당 데이터에 더 많은 키 / 값을 추가하거나 응용 프로그램을 향상시킬 때마다 오류가 발생하기 쉽습니다.
-
방법은 발신자와 서비스 간의 계약입니다. 메소드에서 가장 중요한 것은 입력 및 출력입니다. 이 입력과 출력은 쉽게 읽고 이해할 수 있고 자체 문서화되어야합니다. Person 클래스를 이름, 성, 나이가 포함 된 반환 값으로 사용하는 경우 자체 문서화입니다. 이를 위해 Javadoc을 생성하면 사용자가 클래스를 탐색하여이를보다 잘 이해할 수 있습니다. 해시 테이블을 사용하는 경우 상황이 바뀌면 아무도 읽거나 업데이트하지 않을 주석으로 해시 테이블을 설명해야합니다.
-
HashMap<String,String>
return 문에 숫자 (연령)를 추가하려는 경우 와 같이 제네릭을 사용할 수 없습니다 . generics를 사용하지 않으면 객체 간을 실제 유형으로 캐스트해야합니다. 동적 입력을 사용하는 경우이를 저장할 수 있습니다. -
또한 컴파일 타임에 문제를 잡는 것보다 런타임 실패 가능성이 더 높습니다. 예를 들어 누군가 해시 맵에서 항목을 삭제하고 이전 호출자 중 하나가 항목을 예상하는 경우 클라이언트는 런타임 중에 실패합니다. 컴파일 타임 에이 문제를 잡는 것이 항상 좋습니다.
-
해시 맵을 리턴 유형으로 사용하려는 경우 불변 유형을 리턴하기가 어렵습니다. 그러나 사용자가 자신의 유형을 정의한 사용자를 사용하는 경우이를 제어 할 수 있습니다.
처음에는 클래스를 두 개 만들지 않아도되기 때문에 해시 맵을 반환 형식으로 사용하고 싶은 유혹이 있지만 앞으로 코드를 유지하는 것은 악몽이 될 것입니다. 객체 지향 !!!!
답변
문제 중 하나는 많은 경우 해시 테이블의 키가 문자열이라는 것입니다. 따라서이 방법의 소비자는 데이터를 추출하는 데 사용할 키를 미리 알고 있어야합니다. 이는 데이터에 액세스 할 때 철자가 틀리면 오류가 발생할 가능성이 있습니다.
또 다른 단점은 리팩토링입니다. 나중에 멤버의 이름을 변경하기로 결정한 경우 변경해야 할 많은 마법 줄이 있습니다. 가장 훌륭한 IDE에서 제공하는 리팩토링 도구를 사용하여 클래스 멤버의 이름을 바꾸는 것이 훨씬 간단합니다. 해시 테이블을 사용하면 문제가 될 수있는 모든 소스 파일에서 찾기 / 바꾸기 작업을 수행해야 할 것입니다.
마지막으로, 이름과 유형 측면에서 멤버 액세스의 컴파일 시간 검사가 손실됩니다. 후자는 해시 테이블에 하나의 유형의 객체 만 포함되어 있지만 동일한 계층 구조 체인에 많은 유형이 포함되어 있으면 실제로 언어의 유형 시스템을 활용하고 컴파일 시간을 확인하려고합니다. 대부분의 IDE에는 일종의 지능 / 자동 완성 기능이 있습니다.이 유형 시스템을 보면 작동하지만 해시 테이블 키로는 도움이되지 않습니다.
이 시간에 관해서는 것이다 값 둘 때 해시 테이블 (또는 키 값 쌍 등의 모음)을 반환하는 것이 적절할 수, 당신은이을 사용 하고 키가 컴파일 타임에 확인되지 않을 수도 있습니다. 예를 들어 쿼리 문자열을 구문 분석하고 키 및 해당 값을 반환하는 메서드가있는 경우 해시 테이블을 선택하는 것이 좋습니다. 이 경우 어떤 종류의 불변 또는 읽기 전용 해시 테이블 반환에 대해 생각할 수도 있습니다.
편집 -이 답변에서 제기 된 대부분의 포인트는 동적 언어에 대해 이야기 할 때 적용되지 않습니다 🙂
답변
이에 대한 가장 중요한 주장은 소비자에게 너무 많은 정보를 노출하고 있다는 것입니다. 소비 코드는 코드가 일종의 키-값 수집 (사전)임을 알면됩니다. 해시 맵으로 구현되는지, 연관 목록, 트리 또는 기타 무엇이든간에 상대적으로 관심이 없습니다. 따라서 올바른 방법은 IDictionary
실제 유형 대신 적절한 인터페이스 ( 또는 선택한 언어가 사용하는 모든 것)로 반환하는 것입니다.
데이터를 표현하기 위해 실제로 사전이 필요하다고 가정 할 때, 즉 데이터는 키 / 값 쌍으로 구성되며, 여기서 키는 데이터 집합간에 고유하며 컴파일 타임에 수정할 수 없습니다. 미리 알려진 키가있는 경우 데이터에 적합한 유형 (또는 필요에 따라 여러 유형)을 작성해야합니다. 키 자체를 데이터의 일부 또는 코드의 일부로 간주하는지 여부가 결정됩니다.
편집 :
명확히하기 위해 여기서는 가장 일반적인 유형의 키-값 데이터 구조를 의미 하기 위해 사전 이라는 용어를 사용하고 있습니다. 파이썬 dict
이나 .NET 과 같은 언어 별 구현을 의미하지는 않습니다 Dictionary
.
답변
제가 스스로 물어볼 질문 중 하나는 “이 사전에서 키가 바뀌고 있습니까?”입니다. 이들이 일정한 경우 객체 또는 다른 적절한 데이터 구조를 반환해야합니다. 동적 인 경우 사전 스타일 구조를 반환 할 수 있습니다. 마지막으로, 일정하게 될 일부 키와 알려지지 않은 동적 키 세트가 있으면 고정 값과 오버플로에 대한 사전을 포함하는 하이브리드 데이터 구조를 반환 할 수 있습니다.