Saya memiliki peta berikut:
Map<Double, List<SoundEvent>> soundEventCells = new HashMap<Double, List<SoundEvent>>();
Ini HashMap
memetakan double
nilai (yang merupakan titik waktu) ke SoundEvent
'sel' yang sesuai : setiap 'sel' dapat berisi sejumlah SoundEvent
s. Itu sebabnya ini diimplementasikan sebagai List<SoundEvent>
, karena memang seperti itu.
Demi keterbacaan kode yang lebih baik, saya berpikir untuk mengimplementasikan kelas internal statis yang sangat sederhana seperti:
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
}
Dan daripada deklarasi peta (dan banyak kode lainnya) akan terlihat lebih baik, misalnya:
Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();
Apakah ini berlebihan? Apakah Anda melakukan ini dalam proyek Anda?
java
design
object-oriented
Aviv Cohn
sumber
sumber
private static
karena itu hanya akan digunakan oleh kelas luar, tetapi tidak terkait dengan contoh spesifik dari kelas luar. Bukankah itu penggunaan yang tepatprivate static
?Jawaban:
Sama sekali tidak berlebihan. Mulailah dengan operasi yang Anda butuhkan, daripada memulai dengan "Saya bisa menggunakan HashMap". Terkadang, HashMap adalah yang Anda butuhkan.
Dalam kasus Anda, saya kira tidak. Yang mungkin ingin Anda lakukan adalah sesuatu seperti ini:
Anda pasti tidak ingin memiliki banyak kode yang mengatakan ini:
Atau mungkin Anda bisa menggunakan salah satu implementasi Multimap Guava .
sumber
TimeLine
kelas tepat untuk hal semacam itu :) Ini pembungkus tipis sekitarHashMap<Double, SoundEventCell>
(akhirnya aku pergi denganSoundEventCell
bukanList<SoundEvent>
ide). Jadi saya hanya bisa melakukantimeline.addEvent(4.5, new SoundEvent(..))
dan memiliki hal-hal tingkat rendah dienkapsulasi :)Meskipun dapat membantu keterbacaan di beberapa daerah, hal ini juga dapat memperumit masalah. Saya pribadi menjauh dari membungkus atau memperluas koleksi demi kelancaran, karena pembungkus baru, pada bacaan awal, menyiratkan kepada saya bahwa mungkin ada perilaku yang perlu saya waspadai. Anggap itu sebagai naungan Prinsip Terkejut.
Tetap dengan implementasi antarmuka berarti saya hanya perlu khawatir tentang antarmuka. Implementasi konkretnya, tentu saja, dapat menampung perilaku tambahan, tetapi saya tidak perlu khawatir tentang hal itu. Jadi, ketika saya mencoba mencari jalan melalui kode seseorang, saya lebih suka antarmuka yang mudah dibaca.
Jika, di sisi lain, Anda menemukan kasus penggunaan yang tidak manfaat dari perilaku menambahkan, maka Anda memiliki argumen untuk meningkatkan kode dengan menciptakan kelas matang penuh.
sumber
List
bisa dilakukan, dan melakukan semua itu untuk alasan yang baik.SoundEventCell
dapat menerapkanIterable
untukSoundEvent
s, yang akan menawarkan iteratorsoundEvents
anggota, sehingga Anda akan dapat membaca (tetapi tidak menulis) sebagai daftar apa pun. Saya ragu untuk menutupi kerumitan hampir sebanyak saya ragu untuk menggunakanList
ketika saya mungkin membutuhkan sesuatu yang lebih dinamis di masa depan.Membungkusnya membatasi fungsionalitas Anda hanya pada metode yang Anda putuskan untuk ditulis, pada dasarnya meningkatkan kode Anda tanpa manfaat. Paling tidak, saya akan mencoba yang berikut:
Anda masih dapat menulis kode dari contoh Anda.
Yang mengatakan, saya hanya pernah melakukan ini ketika ada beberapa fungsi yang dibutuhkan daftar itu sendiri. Tapi saya pikir metode Anda akan berlebihan dalam hal ini. Kecuali Anda memiliki alasan untuk membatasi akses ke sebagian besar metode Daftar.
sumber
Solusi lain mungkin mendefinisikan kelas pembungkus Anda dengan metode tunggal yang memaparkan daftar:
Ini memberi Anda kelas yang dinamai dengan kode minimal, tetapi masih memberi Anda enkapsulasi, memungkinkan Anda untuk membuat misal membuat kelas tidak berubah (dengan melakukan salinan defensif di konstruktor dan menggunakan
Collections.unmodifiableList
di accessor).(Namun, jika daftar ini memang hanya digunakan di kelas ini, saya pikir Anda akan lebih baik untuk mengganti Anda
Map<Double, List<SoundEvent>>
denganMultimap<Double, SoundEvent>
( docs ), karena itu sering menyimpan banyak logika dan kesalahan pemeriksaan-nol.)sumber