Jadi saya cukup baru dalam pemrograman di dunia nyata (di luar proyek akademik) dan telah menemukan banyak posting yang mengatakan bahwa menggunakan instanceof
adalah hal yang buruk untuk digunakan untuk menentukan kelas apa objek tertentu.
Situasi saya adalah saya memiliki tiga kelas, kelas produk dasar, satu yang memanjang dari itu dan yang lain memanjang dari itu. Ini semua disimpan dalam tabel yang sama dalam database dan saya memiliki beberapa kode yang perlu menggunakan metode pada masing-masing untuk menarik data dari mereka.
Apa praktik terbaik untuk menyiasati cara melakukannya? Saya telah membaca beberapa hal tentang polimorfisme tetapi saya tidak dapat menemukan contoh yang memperbaiki masalah yang saya miliki. Mereka semua biasanya menimpa metode yang bagi saya tidak akan berfungsi karena saya harus menarik hal-hal yang berbeda dari objek yang berbeda.
Apakah ada cara yang lebih baik untuk melakukan ini atau saya terjebak dengan menggunakan instanceof
atau semacam refleksi untuk mendapatkan bidang khusus untuk objek?
sumber
instanceof
salah; mencoba menemukan kelas suatu objek biasanya merupakan masalah. Tidak selalu salah, tetapi mungkin dalam kasus Anda itu. Mungkin jika Anda memberi tahu kami apa yang ingin Anda capai, kami dapat menyarankan solusi menggunakan polimorfisme.getSpecifics()
yang diimplementasikan secara berbeda pada masing-masing, dengan masing-masing mengembalikan data spesifik ke kelas?Jawaban:
Alasannya
instanceof
adalah berkecil hati adalah bahwa itu bukan OOP.Seharusnya tidak ada alasan bagi penelepon / pengguna suatu objek untuk mengetahui kelas konkret mana yang merupakan turunan dari tipe variabel yang dinyatakannya.
Jika Anda memerlukan perilaku berbeda dalam subkelas, tambahkan metode dan implementasikan secara berbeda.
sumber
getSpecifics()
(atau yang serupa) pada setiap kelas yang akan mengembalikan spesifik untuk setiap kelas. Apakah ini pendekatan terbaik?List
. Saya meneruskannya ke objek yang mengambilIterable
. Sekarang objek kedua meneruskannya ke objek ketiga yang mengambil salah satuList
untuk optimasi, atauIterable
tetapi jauh lebih lambat. Yang kedua seharusnya tidak tahu bahwa itu daftar, tetapi yang ketiga sangat ingin tahu. Bukankah objek ketiga harus memeriksa instanceof untuk melihat apakah ia dapat menerapkan optimasi? Lihat misalnya jambu bijiFluentIterable
yang melakukan hal itu.instanceof
.instanceof
tidak selalu merupakan hal yang buruk, namun itu adalah sesuatu yang harus dilihat.Contoh di mana ia bekerja dengan benar adalah di tempat di mana seseorang mendapatkan koleksi tipe dasar dan Anda hanya ingin yang subtipe. Mendapatkan alamat jaringan dari
NetworkInterface.getNetworkInterfaces()
mengembalikan kembali objek NetworkInterface yang memiliki koleksi objek InetAddress, beberapa di antaranya adalah Inet4Address dan beberapa di antaranya adalah Inet6Address. Jika seseorang ingin memfilter koleksi untuk objek Inet4Address, perlu menggunakan instanceof.Dalam situasi yang dijelaskan di posting asli, ada kelas Base, sesuatu yang memperluas kelas dasar itu dan sesuatu yang memperluas kelas diperluas. Meskipun tidak sepenuhnya informatif, ini tampaknya memiliki dasar dari beberapa desain yang kurang ideal.
Ketika Anda mengembalikan kelas dasar kecuali ada alasan yang baik untuk itu dirancang seperti itu (kompatibilitas mundur antara spesifikasi versi sebelumnya) Anda tidak harus mencoba mengintip jenis yang mendasarinya. Jika Anda mengembalikan Set, Anda tahu Anda mendapatkan set. Ini memungkinkan pengembang untuk kemudian mengubah pikirannya untuk mengembalikan tipe yang lebih spesifik (SortedSet) atau mengubah tipe yang mendasarinya (HashSet ke TreeSet) tanpa merusak apa pun.
Pertimbangkan kembali desain Anda tentang bagaimana objek terstruktur dan diasuh untuk melihat apakah seseorang dapat membuat model kelas yang lebih baik yang tidak memerlukan perbedaan jenis.
sumber
isOfType(SomeEnum.IPv4)
metode bisa menjadi cara yang lebih baik untuk menyaring kualitas seperti itu daripada memeriksa jenis beton melaluiinstanceof
. Bagaimana jika Anda ingin membagi kelas implementasi IPv4 Anda nanti? Bukannya ini selalu lebih baik, tapi itu pertimbangan.(o instanceof Serializable) || (o instanceof Externalizable)
. instanceof lebih baik daripada alternatifAnda dapat menggunakan metode getClass ().
Apakah Anda yakin perlu tiga kelas berbeda? Mungkin satu kelas dengan saklar di dalam akan melayani lebih baik?
sumber
getClass
daninstanceof
berbagi kerugian. Polimorfisme lebih baik daripada keduanya ketika cocok, dan saya tidak melihatnya tidak cocok dengan kasus penggunaan OP.getClass
apakah saya masih berbagi masalah yang sama dengan menggunakaninstanceof
? Saya masih harus mencari tahu yang saya miliki dan kemudian memanggil satu set fungsi. Idealnya saya ingin metode yang mengembalikan data spesifik ke kelas itu tanpa perlu dilemparkan ke objek itu.getClass
adalah cara yang lebih baik untuk melakukannya, itu tidak ada urusan mengambil sebagian besar jawaban ;-)Biasanya ketika saya menemukan diri saya ingin tahu jenis sesuatu itu berarti saya menerapkan struktur objek yang salah. Sebagian besar kali ini karena melanggar LSP .
Namun ada saat di mana saya berharap saya memiliki cara untuk melakukan pengiriman dinamis dan menghemat satu ton kode pelat ketel dan memperbaiki struktur objek saya. C # memberikan kata kunci dinamis dalam angsuran kerangka kerja yang lebih baru tetapi sejauh yang saya tahu Java masih tidak memiliki sesuatu yang serupa.
Yang mengatakan, instanceof umumnya lebih baik daripada membandingkan kelas karena akan mendukung warisan dengan benar. Anda juga dapat menggunakan metode seperti issignableFrom dan lainnya dari API refleksi. Jika Anda ingin mengimplementasikan sesuatu seperti pengiriman dinamis, itu bisa dilakukan melalui API refleksi tetapi waspadalah, itu akan lambat. Gunakan dengan hati-hati, idealnya Anda harus memperbaiki struktur objek dan desing aplikasi Anda jika Anda bisa.
Semoga ini membantu
sumber