가독성을 높이기 위해 간단한 클래스로 컬렉션을 감싸는 것이 과잉입니까?


15

다음과 같은지도가 있습니다.

Map<Double, List<SoundEvent>> soundEventCells = new HashMap<Double, List<SoundEvent>>();

이는 값 (시점)을 해당 '셀'에 HashMap매핑 double합니다 SoundEvent. 각 '셀'에는 여러 개의을 포함 할 수 있습니다 SoundEvent. 그것이 그것이 List<SoundEvent>정확히 그것이 기 때문에 그것이 로 구현 된 이유 입니다.

코드의 가독성을 높이기 위해 매우 간단한 정적 내부 클래스를 구현하는 방법을 생각했습니다.

private static class SoundEventCell {
    private List<SoundEvent> soundEvents = new ArrayList<SoundEvent>();
    public void addEvent(SoundEvent event){
        soundEvents.add(event);
    }
    public int getSize(){
        return soundEvents.size();
    }
    public SoundEvent getEvent(int index){
        return soundEvents.get(index);
    }
    // .. remove() method unneeded
}

그리고지도 선언 (및 다른 많은 코드)보다 예를 들어 다음과 같습니다.

Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();

이것은 과잉입니까? 프로젝트에서이 작업을 수행 하시겠습니까?


개념적으로, 이것은 읽기 쉽고 유지 관리가 쉬운 코드를 작성했는지 어떻게 알 수 있습니까? 동료들이 당신의 일을하는 방식에 대해 계속 불평한다면, 어떤 방식 으로든 다른 방식 으로든 기분이 나아지도록 더 나은 변화를 가지십시오
gnat

1
사운드 이벤트 목록을 목록이 아닌 "셀"로 만드는 것은 무엇입니까? 이 단어 선택은 셀이 목록과 다르거 나 결국 동작과 다름을 의미합니까?
x-code

@DocBrown 왜? 클래스는 private static외부 클래스에서만 사용되기 때문에 외부 클래스의 특정 인스턴스와 관련이 없습니다. 그것이 정확히 올바른 사용법 private static입니까?
Aviv Cohn

2
@Doc Brown, Aviv Cohn : 언어를 지정하는 태그가 없으므로 동시에 모든 것이 옳고 그름 일 수 있습니다!
Emilio Garavaglia

@EmilioGaravaglia : Java (구문으로 판단한 이후 Java 또는 C # 일 수 있으며 관례에 따라 Java로 범위가 좁아집니다.)).
Aviv Cohn

답변:


12

전혀 과잉이 아닙니다. "HashMap을 사용할 수 있습니다"로 시작하지 말고 필요한 작업으로 시작하십시오. 때로는 HashMap이 필요한 것입니다.
귀하의 경우에는 그렇지 않은 것 같습니다. 아마 당신이하고 싶은 것은 다음과 같습니다 :

public class EventsByTime {
    public EventsByTime addEvent(double time, SoundEvent e);
    public List<SoundEvent> getEvents(double time);
    // ... more methods specific to your use ...
}

당신은 분명히 이것을 말하는 많은 코드를 원하지 않습니다 :

List<SoundEvent> events = eventMap.get(time);
if (events == null) {
   events = new ArrayList<SoundEvent>();
   eventMap.put(time, events);
}

아니면 Guava Multimap 구현 중 하나를 사용할 수도 있습니다 .


따라서 정보 숨기기 메커니즘 인 정보 숨기기 메커니즘 인 클래스를 사용하도록 권장합니다. 공포.
Robert Harvey

1
실제로 네, TimeLine그런 종류의 클래스를 가지고 있습니다 :) 그것은 얇은 래퍼입니다 HashMap<Double, SoundEventCell>(결국 아이디어 SoundEventCell대신에 List<SoundEvent>갔습니다). 그래서 나는 할 수 timeline.addEvent(4.5, new SoundEvent(..))있고 하위 레벨의 것들을 캡슐화 할 수 있습니다 :)
Aviv Cohn

14

일부 영역에서는 가독성을 높이는 데 도움이 될 수 있지만 문제가 복잡해질 수도 있습니다. 나는 처음 읽을 때 새로운 래퍼가 내가 알아야 할 행동이있을 수 있음을 암시하므로 유창성을 위해 컬렉션을 감싸거나 확장하는 것을 개인적으로 멀리합니다. 그것을 서프라이즈 서프라이즈의 그늘이라고 생각하십시오.

인터페이스 구현을 고수한다는 것은 인터페이스에 대해서만 걱정할 필요가 있음을 의미합니다. 물론 구체적인 구현에는 추가 동작이 포함될 수 있지만 걱정할 필요는 없습니다. 따라서 누군가의 코드를 통해 길을 찾으려 할 때 가독성을 위해 일반 인터페이스를 선호합니다.

반면에, 당신이 사용 사례 발견하는 경우 않는 추가 행동에서 혜택을, 당신은 전체 깃털 클래스를 생성하여 코드를 개선하기위한 인수가 있습니다.


11
래퍼는 불필요한 동작 을 제거 하거나 숨길 수도 있습니다.
로마 라이너

4
@RomanReiner-나는 그런 것들에 대해주의해야합니다. 오늘날 불필요한 행동은 프로그래머가 내일 당신의 이름을 저주하는 것입니다. 모든 사람이 List할 수 있는 일을 알고 있으며 , 합당한 이유 때문에 모든 것을 수행합니다.
Telastyn

솔루션이 기능과 추상화 사이의 신중한 균형이라고 생각하지만 기능을 유지하려는 열망에 감사드립니다. SoundEventCell구현할 수 Iterable에 대한 SoundEvent의 반복자 제공 할 것이다,의 soundEvents어떤 목록으로 읽기 (쓰기는하지 않음) 할 수있을 것입니다, 그래서 멤버. 나는 List미래에 좀 더 역동적 인 것을 필요 로 할 때 주저하는만큼 복잡성을 숨기는 것을 주저합니다 .

2

랩핑은 작성하기로 결정한 메소드로만 기능을 제한하며, 기본적으로 코드를 증가시키지 않습니다. 최소한 다음을 시도합니다.

private static class SoundEventCell : List<SoundEvent>
{
}

여전히 예제에서 코드를 작성할 수 있습니다.

Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();

즉, 목록 자체에 필요한 기능이있을 때만이 작업을 수행했습니다. 그러나 나는 당신의 방법이 이것에 과잉 일 것이라고 생각합니다. List의 메소드 대부분에 대한 액세스를 제한하려는 이유가없는 한.


-1

또 다른 해결책은 목록을 공개하는 단일 메소드로 랩퍼 클래스를 정의하는 것입니다.

private static class SoundEventCell
{
    private List<SoundEvent> events;

    public SoundEventCell(List<SoundEvent> events)
    {
        this.events = events;
    }

    public List<SoundEvent> getEvents()
    {
        return events;
    }
}

이것은 최소한의 코드로 잘 명명 된 클래스를 제공하지만 캡슐화를 제공하여 클래스를 불변으로 만들 수 있습니다 (예 : 생성자에서 방어 적 복사를 수행 Collections.unmodifiableList하고 접근 자에서 사용 ).

(이 목록은 실제로에만이 클래스에서 사용되는 경우, 난 당신을 대체 할 더 잘 할 거라고 생각 Map<Double, List<SoundEvent>>로모그래퍼 Multimap<Double, SoundEvent>( 문서 가 종종 널 (null) 검사 논리와 오류를 많이 절약 할).)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.