ImmutableMap 또는 Map을 반환하는 것이 더 낫습니까?
Map을 반환해야하는 메서드를 작성하고 있다고 가정 해 보겠습니다 . 예를 들면 :
public Map<String, Integer> foo() {
return new HashMap<String, Integer>();
}
잠시 생각한 끝에이 맵이 생성되면 수정할 이유가 없다고 판단했습니다. 따라서 ImmutableMap 을 반환하고 싶습니다 .
public Map<String, Integer> foo() {
return ImmutableMap.of();
}
반환 유형을 일반 맵으로 두어야합니까, 아니면 ImmutableMap을 반환하도록 지정해야합니까?
한쪽에서, 이것이 바로 인터페이스가 만들어진 이유입니다. 구현 세부 정보를 숨 깁니다.
반면에 이렇게두면 다른 개발자는이 객체가 불변이라는 사실을 놓칠 수 있습니다. 따라서 불변 객체라는 주요 목표를 달성하지 못할 것입니다. 변경할 수있는 개체 수를 최소화하여 코드를 더 명확하게 만듭니다. 최악의 경우, 잠시 후 누군가이 객체를 변경하려고 시도 할 수 있으며 이로 인해 런타임 오류가 발생합니다 (컴파일러가 이에 대해 경고하지 않음).
공개 API를 작성 중이고 불변성이 디자인의 중요한 측면 인 경우 메서드 이름이 반환 된 맵이 불변임을 명확하게 나타내거나 구체적인 유형을 반환하여 명시 적으로 만들 것입니다. 지도. 제 생각에는 javadoc에서 언급하는 것만으로는 충분하지 않습니다.
분명히 Guava 구현을 사용하고 있기 때문에 문서를 보았고 추상 클래스이므로 실제 구체적인 유형에 약간의 유연성을 제공합니다.
내부 도구 / 라이브러리를 작성하는 경우 일반
Map
. 사람들은 자신이 호출하는 코드의 내부에 대해 알거나 최소한 쉽게 액세스 할 수 있습니다.
내 결론은 명백한 것이 좋다는 것입니다. 일을 우연에 맡기지 마십시오.
ImmutableMap
반환 유형으로 가지고 있어야 합니다. Map
구현에 의해 지원되지 않는 방법을 포함 ImmutableMap
(예 put
) 및 표시된 @deprecated
하여 ImmutableMap
.
더 이상 사용되지 않는 메서드를 사용하면 컴파일러 경고가 발생하며 대부분의 IDE는 사람들이 더 이상 사용되지 않는 메서드를 사용하려고 할 때 경고합니다.
이 고급 경고는 무언가 잘못되었다는 첫 번째 힌트로 런타임 예외를 갖는 것보다 낫습니다.
반면에 이렇게두면 다른 개발자는이 객체가 불변이라는 사실을 놓칠 수 있습니다.
javadocs에서 언급해야합니다. 개발자들은 그것들을 읽습니다.
따라서 불변 객체라는 주요 목표를 달성하지 못할 것입니다. 변경할 수있는 개체 수를 최소화하여 코드를 더 명확하게 만듭니다. 최악의 경우, 잠시 후 누군가이 객체를 변경하려고 시도 할 수 있으며 이로 인해 런타임 오류가 발생합니다 (컴파일러가 이에 대해 경고하지 않음).
테스트되지 않은 코드를 게시하는 개발자는 없습니다. 그리고 그가 그것을 테스트 할 때, 그는 이유뿐만 아니라 그가 불변의 맵에 쓰려고 한 파일과 줄을 볼 때 예외가 발생합니다.
그러나 Map
포함 된 객체가 아닌 자체 만 변경할 수 없습니다.
이렇게두면 다른 개발자가이 객체가 불변이라는 사실을 놓칠 수 있습니다.
사실이지만 다른 개발자는 자신의 코드를 테스트하고 코드가 적용되는지 확인해야합니다.
그럼에도 불구하고이 문제를 해결할 수있는 두 가지 옵션이 더 있습니다.
Javadoc 사용
@return a immutable map
설명이 포함 된 메서드 이름을 선택했습니다.
public Map<String, Integer> getImmutableMap() public Map<String, Integer> getUnmodifiableEntries()
구체적인 사용 사례의 경우 메서드 이름을 더 잘 지정할 수도 있습니다. 예
public Map<String, Integer> getUnmodifiableCountByWords()
너는 어떤 다른 일을 할 수 있니?!
당신은 반환 할 수 있습니다
부
private Map<String, Integer> myMap; public Map<String, Integer> foo() { return new HashMap<String, Integer>(myMap); }
이 방법은 많은 클라이언트가 맵을 수정할 것으로 예상하고 맵에 몇 개의 항목 만 포함되어있는 한 사용해야합니다.
CopyOnWriteMap
COW 컬렉션은 일반적으로
동시성 을 처리해야 할 때 사용됩니다 . 그러나 CopyOnWriteMap은 변경 작업 (예 : 추가, 제거)에서 내부 데이터 구조의 복사본을 생성하기 때문에이 개념은 상황에서도 도움이 될 것입니다.이 경우 변경 작업을 제외하고 모든 메서드 호출을 기본 맵에 위임하는 맵 주위에 얇은 래퍼가 필요합니다. 변경 작업이 호출되면 기본 맵의 복사본을 만들고 모든 추가 호출이이 복사본에 위임됩니다.
This approach should be used if you expect that some clients will modify the map.
Sadly java does not have such a
CopyOnWriteMap
. But you might find a third party or implement it by yourself.
At last you should keep in mind that the elements in your map might still be mutable.
Definitely return an ImmutableMap, justification being:
- The method signature (including return type) should be self-documenting. Comments are like customer service: if your clients need to rely on them, then your primary product is defective.
- Whether something is an interface or a class is only relevant when extending or implementing it. Given an instance (object), 99% of the time client code will not know or care whether something is an interface or a class. I assumed at first that ImmutableMap was an interface. Only after I clicked the link did I realize it is a class.
It depends on the class itself. Guava's ImmutableMap
isn't intended to be an immutable view into a mutable class. If your class is immutable and has some structure that is basically an ImmutableMap
, then make the return type ImmutableMap
. However, if your class is mutable, don't. If you have this:
public ImmutableMap<String, Integer> foo() {
return ImmutableMap.copyOf(internalMap);
}
Guava will copy the map every time. That's slow. But if internalMap
was already an ImmutableMap
, then it's totally fine.
If you don't restrict your class to returning ImmutableMap
, then you could instead return Collections.unmodifiableMap
like so:
public Map<String, Integer> foo() {
return Collections.unmodifiableMap(internalMap);
}
Note that this is an immutable view into the map. If internalMap
changes, so will a cached copy of Collections.unmodifiableMap(internalMap)
. I still prefer it for getters, however.
This is not answering the exact question, but it is still worth considering whether a map should be returned at all. If the map is immutable, then the primary method to be provided is based on the get(key):
public Integer fooOf(String key) {
return map.get(key);
}
This makes the API much tighter. If a map is actually required, this could be left up to the client of the API by providing a stream of entries:
public Stream<Map.Entry<String, Integer>> foos() {
map.entrySet().stream()
}
Then the client can make its own immutable or mutable map as it needs, or add the entries to its own map. If the client needs to know if the value exists, optional can be returned instead:
public Optional<Integer> fooOf(String key) {
return Optional.ofNullable(map.get(key));
}
Immutable Map is a type of Map. So leaving the return type of Map is okay.
To ensure that the users do not modify the returned object, the documentation of the method can describe the characteristics of the returned object.
This is arguably a matter of opinion, but the better idea here is to use an interface for the map class. This interface doesn't need to explicitly say that it is immutable, but the message will be the same if you don't expose any of the setter methods of the parent class in the interface.
Take a look at the following article:
참고URL : https://stackoverflow.com/questions/38087900/is-it-better-to-return-an-immutablemap-or-a-map
'Programing' 카테고리의 다른 글
내비게이션 컨트롤러가 내장 된 팝 오버는 후면 내비게이션의 크기를 고려하지 않습니다 (0) | 2020.09.10 |
---|---|
내 서버에 Github를 설치하려면 어떻게해야합니까? (0) | 2020.09.10 |
jquery를 사용하여 iframe의 콘텐츠를 동적으로 변경하려면 어떻게해야합니까? (0) | 2020.09.10 |
사용자 정의 이미지가 있고 테두리가없는 UIBarButtonItem (0) | 2020.09.10 |
게터, 세터 및 속성 모범 사례. (0) | 2020.09.10 |