공개 메소드에서 해시 테이블을 반환하는 데 무엇이 문제가 있으며 언제 그렇게해야합니까?


9

클래스를 만들고 객체를 반환하는 대신 여러 항목을 반환하려는 경우 공용 메서드에서 해시 테이블을 반환 할 때의 디자인 문제는 무엇입니까?

문제가 있다면 어떤 상황에서 그렇게하는 것이 합리적입니까?

이 질문에 대한 답은 언어가 동적인지 아닌지에 따라 어떻게 변합니까?

편집 : 이것은 키가 일정하고 데이터가 아닌 코드의 일부임을 분명히하기 위해입니다. 우리가 일반적으로 클래스를 만드는 것. 문제는 클래스를 만드는 것이 실제로 올바른 선택 인 경우 대신 해시 테이블을 사용하는 것이 왜 잘못된 것입니까?

답변:


11

이름 / 값 쌍으로 임의의 수의 값을 보유하는 해시 테이블보다 더 잘 정의 된 클래스를 리턴 유형으로 사용하십시오.

  1. 가장 중요한 첫 번째 요점은 유지 관리 성입니다. 새로운 프로그래머는 코드를 살펴보면 메소드가 리턴하는 값이 무엇인지 말할 수 없습니다. 새로운 사람이 코드를보고이를 이해하지 못하면 코드가 유용하지 않으며 누군가가 해당 데이터에 더 많은 키 / 값을 추가하거나 응용 프로그램을 향상시킬 때마다 오류가 발생하기 쉽습니다.

  2. 방법은 발신자와 서비스 간의 계약입니다. 메소드에서 가장 중요한 것은 입력 및 출력입니다. 이 입력과 출력은 쉽게 읽고 이해할 수 있고 자체 문서화되어야합니다. Person 클래스를 이름, 성, 나이가 포함 된 반환 값으로 사용하는 경우 자체 문서화입니다. 이를 위해 Javadoc을 생성하면 사용자가 클래스를 탐색하여이를보다 잘 이해할 수 있습니다. 해시 테이블을 사용하는 경우 상황이 바뀌면 아무도 읽거나 업데이트하지 않을 주석으로 해시 테이블을 설명해야합니다.

  3. HashMap<String,String>return 문에 숫자 (연령)를 추가하려는 경우 와 같이 제네릭을 사용할 수 없습니다 . generics를 사용하지 않으면 객체 간을 실제 유형으로 캐스트해야합니다. 동적 입력을 사용하는 경우이를 저장할 수 있습니다.

  4. 또한 컴파일 타임에 문제를 잡는 것보다 런타임 실패 가능성이 더 높습니다. 예를 들어 누군가 해시 맵에서 항목을 삭제하고 이전 호출자 중 하나가 항목을 예상하는 경우 클라이언트는 런타임 중에 실패합니다. 컴파일 타임 에이 문제를 잡는 것이 항상 좋습니다.

  5. 해시 맵을 리턴 유형으로 사용하려는 경우 불변 유형을 리턴하기가 어렵습니다. 그러나 사용자가 자신의 유형을 정의한 사용자를 사용하는 경우이를 제어 할 수 있습니다.

처음에는 클래스를 두 개 만들지 않아도되기 때문에 해시 맵을 반환 형식으로 사용하고 싶은 유혹이 있지만 앞으로 코드를 유지하는 것은 악몽이 될 것입니다. 객체 지향 !!!!


1
질문을 올바르게 이해 한 것 같습니다. 감사.
무하마드 하산 칸

8

문제 중 하나는 많은 경우 해시 테이블의 키가 문자열이라는 것입니다. 따라서이 방법의 소비자는 데이터를 추출하는 데 사용할 키를 미리 알고 있어야합니다. 이는 데이터에 액세스 할 때 철자가 틀리면 오류가 발생할 가능성이 있습니다.

또 다른 단점은 리팩토링입니다. 나중에 멤버의 이름을 변경하기로 결정한 경우 변경해야 할 많은 마법 줄이 있습니다. 가장 훌륭한 IDE에서 제공하는 리팩토링 도구를 사용하여 클래스 멤버의 이름을 바꾸는 것이 훨씬 간단합니다. 해시 테이블을 사용하면 문제가 될 수있는 모든 소스 파일에서 찾기 / 바꾸기 작업을 수행해야 할 것입니다.

마지막으로, 이름과 유형 측면에서 멤버 액세스의 컴파일 시간 검사가 손실됩니다. 후자는 해시 테이블에 하나의 유형의 객체 만 포함되어 있지만 동일한 계층 구조 체인에 많은 유형이 포함되어 있으면 실제로 언어의 유형 시스템을 활용하고 컴파일 시간을 확인하려고합니다. 대부분의 IDE에는 일종의 지능 / 자동 완성 기능이 있습니다.이 유형 시스템을 보면 작동하지만 해시 테이블 키로는 도움이되지 않습니다.

이 시간에 관해서는 것이다 값 둘 때 해시 테이블 (또는 키 값 쌍 등의 모음)을 반환하는 것이 적절할 수, 당신은이을 사용 하고 키가 컴파일 타임에 확인되지 않을 수도 있습니다. 예를 들어 쿼리 문자열을 구문 분석하고 키 및 해당 값을 반환하는 메서드가있는 경우 해시 테이블을 선택하는 것이 좋습니다. 이 경우 어떤 종류의 불변 또는 읽기 전용 해시 테이블 반환에 대해 생각할 수도 있습니다.

편집 -이 답변에서 제기 된 대부분의 포인트는 동적 언어에 대해 이야기 할 때 적용되지 않습니다 :)


언어가 역동적이라면 어떨까요?
무하마드 하산 칸

나는 동적 언어의 전문가가 아니므로 다른 사람이 더 나은 답변을 제공 할 수 있습니다. 그러나 동적 언어는 컴파일 타임 유형 검사를 수행하지 않는다는 것을 알고 있습니다. 그러나이 경우 객체를 반환하고 해시 테이블을 반환하는 것은 그리 다르지 않습니다.
MattDavey

3
@Hasan Khan :이 경우 실제로 해시 테이블과 클래스 인스턴스간에 차이가 없을 수 있습니다. 예를 들어, 자바 스크립트에서 모든 객체 해시 테이블이고 object.property는 object [ 'property']와 정확히 동일합니다.
Michael Borgwardt

"해시 테이블을 사용하면 문제가 될 수있는 모든 소스 파일에서 찾기 / 바꾸기 작업을 수행해야 할 것입니다." 당신이 가난한 키를 선택하고 한곳에서 정의되도록 표준 키를 고려하지 않은 경우에만…
Donal Fellows

7

이에 대한 가장 중요한 주장은 소비자에게 너무 많은 정보를 노출하고 있다는 것입니다. 소비 코드는 코드가 일종의 키-값 수집 (사전)임을 알면됩니다. 해시 맵으로 구현되는지, 연관 목록, 트리 또는 기타 무엇이든간에 상대적으로 관심이 없습니다. 따라서 올바른 방법은 IDictionary실제 유형 대신 적절한 인터페이스 ( 또는 선택한 언어가 사용하는 모든 것)로 반환하는 것입니다.

데이터를 표현하기 위해 실제로 사전이 필요하다고 가정 할 때, 즉 데이터는 키 / 값 쌍으로 구성되며, 여기서 키는 데이터 집합간에 고유하며 컴파일 타임에 수정할 수 없습니다. 미리 알려진 키가있는 경우 데이터에 적합한 유형 (또는 필요에 따라 여러 유형)을 작성해야합니다. 키 자체를 데이터의 일부 또는 코드의 일부로 간주하는지 여부가 결정됩니다.

편집 :

명확히하기 위해 여기서는 가장 일반적인 유형의 키-값 데이터 구조를 의미 하기 위해 사전 이라는 용어를 사용하고 있습니다. 파이썬 dict이나 .NET 과 같은 언어 별 구현을 의미하지는 않습니다 Dictionary.


1
"키 자체를 데이터의 일부 또는 코드의 일부로 간주하는지 여부는 +1입니다." -좋은 방법입니다. 예를 들어 '사전'이라는 용어가 '지도'와 얼마나 보편적인지 확실하지 않습니다.
MattDavey

사전을 반환하지 않았습니다. 키는 데이터가 아닌 코드의 일부였습니다.
무하마드 하산 칸

실제 질문은 '적절한 유형을 만들어야한다'는 이유입니다. 질문은 왜입니까?
무하마드 하산 칸

2

제가 스스로 물어볼 질문 중 하나는 "이 사전에서 키가 바뀌고 있습니까?"입니다. 이들이 일정한 경우 객체 또는 다른 적절한 데이터 구조를 반환해야합니다. 동적 인 경우 사전 스타일 구조를 반환 할 수 있습니다. 마지막으로, 일정하게 될 일부 키와 알려지지 않은 동적 키 세트가 있으면 고정 값과 오버플로에 대한 사전을 포함하는 하이브리드 데이터 구조를 반환 할 수 있습니다.


실제로 조언은 정확하지만 문제는 클래스가 더 나은 선택 일 때 해시 테이블을 사용하도록 선택하는 데 문제가 있습니다.
무하마드 하산 칸

/ 또는; 클래스는 필요한 경우 쉽게 사전을 포함 할 수 있습니다.
Wyatt Barnett
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.