Bir koleksiyonu sadece daha iyi okunabilirlik amacıyla basit bir sınıfa sarmak aşırı mıdır?


15

Aşağıdaki haritaya sahibim:

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

Bu, değerleri (zaman içindeki noktalar) karşılık gelen 'hücre' ile HashMapeşleştirir : her 'hücre' bir dizi s içerebilir . Bu yüzden a olarak uygulanır , çünkü tam olarak budur.doubleSoundEventSoundEventList<SoundEvent>

Kodun daha iyi okunabilmesi için şöyle basit bir statik iç sınıf uygulamayı düşündüm:

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
}

Harita beyanından (ve diğer birçok koddan) daha iyi görünür, örneğin:

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

Bu aşırı mı? Bunu projelerinizde yapar mısınız?


biri kavramsal olarak, bunun okunabilir ve kolay korunabilir kod yazıp yazmadığınızı nasıl anlarsınız? Akranlarınız bir şeyleri yapma şeklinizden şikayet etmeye devam ederse, öyle ya da böyle, daha iyi hissetmelerini sağlamak için daha iyi bir değişiklik yapmalısınız
gnat

1
Ses olaylarının listesini liste yerine "hücre" yapan nedir? Bu kelime seçimi, bir hücrenin listeden farklı bir davranışa sahip olduğu veya nihayetinde farklı davranışlara sahip olacağı anlamına mı geliyor?
x-kodu

@DocBrown Neden? Sınıf, private staticbunun yalnızca dış sınıf tarafından kullanılacağı, ancak dış sınıfın belirli bir örneğiyle ilişkili olmamasıdır. Bu tam olarak doğru kullanımı değil private staticmi?
Aviv Cohn

2
@Doc Brown, Aviv Cohn: Herhangi bir dili belirten bir etiket yok, bu yüzden her şey aynı anda doğru ve yanlış olabilir!
Emilio Garavaglia

@EmilioGaravaglia: Java (Bence sözdizimine göre Java veya C # olabilir ve kullanılan kurallar Java'ya daraltır;
Aviv Cohn

Yanıtlar:


12

Hiç abartılı değil. "Bir HashMap Kullanabilirim" ile başlamak yerine, ihtiyacınız olan işlemlerle başlayın. Bazen bir HashMap tam ihtiyacınız olan şeydir.
Sizin durumunuzda olduğundan şüpheleniyorum. Muhtemelen yapmak istediğiniz şey şudur:

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

Kesinlikle bunu söyleyen bir kod grubuna sahip olmak istemezsiniz:

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

Ya da sadece Guava Multimap uygulamalarından birini kullanabilirsiniz .


Yani aslında bir bilgi gizleme mekanizması olan bir sınıfı bir bilgi gizleme mekanizması olarak kullanmayı mı savunuyorsunuz? Korku.
Robert Harvey

1
Aslında evet, TimeLinetam olarak bu tür bir şey için bir sınıf var :) Etrafında ince bir sarıcı HashMap<Double, SoundEventCell>(sonunda fikir SoundEventCellyerine geçirdim List<SoundEvent>). Bu yüzden yapabilirim timeline.addEvent(4.5, new SoundEvent(..))ve daha düşük seviyedeki şeyleri kapsülleyebilirim :)
Aviv Cohn

14

Bazı alanlarda okunabilirliğe yardımcı olsa da, işleri de zorlaştırabilir. Kişisel olarak, akıcılık için koleksiyonları sarmaktan veya uzatmaktan uzağa yaslanıyorum, çünkü yeni ambalaj, ilk okumada, bilmem gereken davranışlar olabileceğini ima ediyor. En Az Sürpriz İlkesinin bir gölgesi olarak düşünün.

Arayüz uygulamasına bağlı kalmak, sadece arayüz hakkında endişelenmem gerektiği anlamına gelir. Somut uygulama, elbette, ek davranışlara ev sahipliği yapabilir, ancak bunun için endişelenmem gerekmiyor. Yani, birinin kodunu kullanarak yolumu bulmaya çalışırken, okunabilirlik için düz arayüzleri tercih ederim.

Öte yandan, bir kullanım durumunda buluyoruz ise yaptığı katma davranışından fayda, o zaman tam teşekküllü bir sınıf oluşturarak kod geliştirmek için bir argüman var.


11
Gereksiz davranışı kaldırmak (veya gizlemek) için bir sarıcı da kullanılabilir .
Roman Reiner

4
@RomanReiner - Bu tür şeylere karşı dikkatli olurum. Bugün gereksiz davranışlar genellikle programcı yarın adınızı lanetliyor. Herkes a'nın ne Listyapabileceğini bilir ve tüm bunları iyi bir nedenden dolayı yapar.
Telastyn

İşlevselliği sürdürme isteğini takdir ediyorum, ancak çözümün işlevsellik ve soyutlama arasında dikkatli bir denge olduğunu düşünüyorum. Üyenin yineleyicisini sunacak olan s için SoundEventCelluygulayabilir , böylece herhangi bir liste olarak okuyabilir (ancak yazamazsınız). Gelecekte daha dinamik bir şeye ihtiyacım olabileceği zaman, neredeyse kullanmaktan çekinmiyorum kadar karmaşıklığı maskelemek için tereddüt ediyorum. IterableSoundEventsoundEventsList
Neil

2

Kaydırmak, işlevselliğinizi yalnızca yazmaya karar verdiğiniz yöntemlerle sınırlar ve temel olarak hiçbir faydası olmadan kodunuzu artırır. En azından aşağıdakileri deneyeceğim:

private static class SoundEventCell : List<SoundEvent>
{
}

Kodu yine de örneğinizden yazabilirsiniz.

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

Bununla birlikte, bunu yalnızca listenin kendisinin ihtiyaç duyduğu bazı işlevler olduğunda yaptım. Ama bence yönteminiz buna fazla gelebilir. List'in yöntemlerinin çoğuna erişimi sınırlamak istemeniz için bir nedeniniz olmadıkça.


-1

Başka bir çözüm, sarmalayıcı sınıfınızı listeyi gösteren tek bir yöntemle tanımlamak olabilir:

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

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

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

Bu size iyi kodlanmış sınıfınızı en az kodla verir, ancak yine de kapsüllemeyi verir, örneğin sınıfı değiştirilemez hale getirmenize izin verir (yapıcıda savunma amaçlı bir kopya yaparak Collections.unmodifiableListve erişimcide kullanarak ).

(Ancak, bu listeler gerçekten sadece bu sınıfta kullanılıyorsa, bence yerine Map<Double, List<SoundEvent>>bir Multimap<Double, SoundEvent>( dokümanlar ) koymak daha iyi olur , çünkü bu genellikle çok sayıda boş denetleme mantığı ve hatası kaydeder.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.