코드 검토 후 디자인 선택에 대해 토론했습니다. 나는 당신의 의견이 무엇인지 궁금합니다.
Preferences
키-값 쌍을위한 버킷 인 이 클래스 가 있습니다 . null 값은 합법적입니다 (중요). 특정 값은 아직 저장되지 않을 것으로 예상되며 요청시 사전 정의 된 기본값으로 초기화하여 이러한 사례를 자동으로 처리하려고합니다.
논의 된 솔루션은 다음 패턴을 사용했습니다 (참고 : 이것은 실제 코드 가 아니며 , 분명히 설명을 위해 단순화되었습니다).
public class Preferences {
// null values are legal
private Map<String, String> valuesFromDatabase;
private static Map<String, String> defaultValues;
class KeyNotFoundException extends Exception {
}
public String getByKey(String key) {
try {
return getValueByKey(key);
} catch (KeyNotFoundException e) {
String defaultValue = defaultValues.get(key);
valuesFromDatabase.put(key, defaultvalue);
return defaultValue;
}
}
private String getValueByKey(String key) throws KeyNotFoundException {
if (valuesFromDatabase.containsKey(key)) {
return valuesFromDatabase.get(key);
} else {
throw new KeyNotFoundException();
}
}
}
흐름을 제어하기 위해 패턴을 남용하지 않는 예외 로 비난 받았다 . KeyNotFoundException
-하나의 유스 케이스에만 생명을 불어 넣었습니다.-이 클래스의 범위를 벗어나지 않습니다.
본질적으로 서로 가져 오기 위해 두 가지 방법으로 가져 오기를 수행합니다.
데이터베이스에 존재하지 않는 키는 놀라운 것이 아니며 예외적입니다. 새로운 환경 설정이 추가 될 때마다 발생할 것으로 예상되므로 필요한 경우 기본값으로 정상적으로 초기화하는 메커니즘입니다.
반론는 것이 었습니다 getValueByKey
지금 정의에 대한 대중 방법을 알리는 자연적인 방법이 없습니다 - 민간 방법 - 두 값을, 여부 키가이었다. 그렇지 않은 경우 값을 업데이트 할 수 있도록 추가해야합니다.
반환 null
은 모호 할 것입니다. 왜냐하면 null
완벽하게 합법적 인 가치이기 때문에 키가 존재하지 않았는지 또는가 있는지를 알 수 없습니다 null
.
getValueByKey
Tuple<Boolean, String>
키가 이미 있으면 bool을 true로 설정하여 일종의 a를 반환해야 하므로 (true, null)
and를 구별 할 수 있습니다 (false, null)
. (과 out
매개 변수는 C #으로 사용하지만 자바의 수).
이것이 더 좋은 대안입니까? 예,의 효과에 대해 일부 일회용 클래스를 정의해야 Tuple<Boolean, String>
하지만, 우리는을 제거 KeyNotFoundException
하여 그런 종류의 균형을 유지합니다. 우리는 또한 예외 처리의 오버 헤드를 피하고 있습니다. 실제적인 용어로는 중요하지는 않지만 성능에 대한 고려 사항은 없으며 클라이언트 응용 프로그램이며 사용자 기본 설정이 초당 수백만 번 검색되는 것과는 다릅니다.
이 접근 방식의 변형은 Optional<String>
일부 사용자 지정 대신 구아바 (구아바는 이미 프로젝트 전체에서 사용됨)를 Tuple<Boolean, String>
사용할 수 있으며 Optional.<String>absent()
, "적절한"을 구분할 수 있습니다 null
. 그래도 이해하기 쉬운 이유로 여전히 해킹을 느낍니다. 두 가지 수준의 "무효 성"을 도입 Optional
하면 처음에는 s를 만드는 데 뒤쳐진 개념을 남용하는 것처럼 보입니다 .
다른 옵션은 키가 존재하는지 명시 적으로 확인하는 것입니다 ( boolean containsKey(String key)
메소드를 추가하고 getValueByKey
이미 존재한다고 주장한 경우에만 호출 하십시오).
마지막으로 개인 메서드를 인라인 할 수도 있지만 실제 getByKey
는 내 코드 샘플보다 다소 복잡하므로 인라이닝하면 상당히 불쾌하게 보일 수 있습니다.
나는 머리카락을 여기에서 나눌 수 있지만,이 경우 모범 사례에 가장 가까운 것에 베팅 한 것이 궁금합니다. Oracle 또는 Google 스타일 가이드에서 답을 찾지 못했습니다.
코드 샘플에서와 같은 예외를 사용하는 것이 안티 패턴입니까, 아니면 대안이 매우 깨끗하지 않은 경우 허용됩니까? 그렇다면 어떤 상황에서 괜찮을까요? 그 반대?
getValueByKey
공개 될 때 질문이 더 흥미로워 진다고 생각합니다 .