Polimorfisme
Selama Anda menggunakan getType()
atau apa pun seperti itu, Anda tidak menggunakan polimorfisme.
Saya mengerti perasaan seperti Anda perlu tahu jenis apa yang Anda miliki. Tetapi pekerjaan apa pun yang ingin Anda lakukan sambil tahu itu harus benar-benar didorong ke dalam kelas. Maka Anda hanya memberi tahu kapan harus melakukannya.
Kode prosedural mendapat informasi kemudian mengambil keputusan. Kode berorientasi objek memberi tahu objek untuk melakukan sesuatu.
- Alec Sharp
Prinsip ini disebut tell, jangan tanya . Mengikutinya membantu Anda tidak menyebarkan detail seperti mengetik di sekitar dan membuat logika yang bekerja pada mereka. Melakukan itu mengubah kelas menjadi luar. Lebih baik menjaga perilaku itu di dalam kelas sehingga bisa berubah ketika kelas berubah.
Enkapsulasi
Anda bisa memberi tahu saya bahwa tidak ada bentuk lain yang akan dibutuhkan, tetapi saya tidak percaya Anda dan begitu juga Anda.
Efek bagus mengikuti enkapsulasi adalah mudah untuk menambahkan tipe baru karena detailnya tidak menyebar ke kode tempat mereka muncul if
dan masuk switch
akal. Kode untuk tipe baru semua harus di satu tempat.
Jenis sistem deteksi tabrakan bodoh
Mari saya tunjukkan bagaimana saya merancang sistem pendeteksian tabrakan yang berkinerja dan bekerja dengan bentuk 2D apa pun dengan tidak peduli dengan jenisnya.
Katakanlah Anda seharusnya menggambar itu. Tampak sederhana. Semuanya lingkaran. Sangat menggoda untuk membuat kelas lingkaran yang memahami tumbukan. Masalahnya adalah ini mengirim kita ke garis pemikiran yang berantakan ketika kita membutuhkan 1000 lingkaran.
Kita seharusnya tidak memikirkan lingkaran. Kita harus memikirkan piksel.
Bagaimana jika saya katakan bahwa kode yang sama yang Anda gunakan untuk menggambar orang-orang ini adalah apa yang dapat Anda gunakan untuk mendeteksi ketika mereka menyentuh atau bahkan yang mana yang diklik pengguna.
Di sini saya telah menggambar setiap lingkaran dengan warna yang unik (jika mata Anda cukup bagus untuk melihat garis hitam, abaikan saja). Ini berarti setiap piksel dalam gambar tersembunyi ini memetakan kembali ke apa yang menariknya. Hashmap menangani hal itu dengan baik. Anda sebenarnya dapat melakukan polimorfisme dengan cara ini.
Gambar ini tidak harus Anda perlihatkan kepada pengguna. Anda membuatnya dengan kode yang sama dengan yang pertama. Hanya dengan warna berbeda.
Ketika pengguna mengklik pada lingkaran saya tahu persis lingkaran mana karena hanya satu lingkaran adalah warna itu.
Ketika saya menggambar lingkaran di atas yang lain saya dapat dengan cepat membaca setiap piksel yang akan saya timpa dengan membuangnya dalam satu set. Ketika saya selesai mengatur poin ke setiap lingkaran yang bertabrakan dan sekarang saya hanya perlu memanggil masing-masing satu kali untuk memberitahukannya tentang tabrakan.
Tipe baru: Persegi panjang
Ini semua dilakukan dengan lingkaran tetapi saya bertanya: apakah akan bekerja berbeda dengan persegi panjang?
Tidak ada pengetahuan lingkaran yang bocor ke sistem deteksi. Itu tidak peduli tentang jari-jari, keliling, atau titik pusat. Itu peduli tentang piksel dan warna.
Satu-satunya bagian dari sistem tabrakan ini yang perlu didorong ke dalam bentuk individual adalah warna yang unik. Selain itu bentuknya bisa saja memikirkan menggambar bentuknya. Itu yang mereka kuasai.
Sekarang ketika Anda menulis logika tabrakan, Anda tidak peduli subtipe apa yang Anda miliki. Anda menyuruhnya bertabrakan dan memberi tahu Anda apa yang ditemukan di bawah bentuk yang berpura-pura menggambar. Tidak perlu tahu tipe. Dan itu berarti Anda dapat menambahkan sub tipe sebanyak yang Anda suka tanpa harus memperbarui kode di kelas lain.
Pilihan implementasi
Sungguh, itu tidak perlu menjadi warna yang unik. Ini bisa menjadi referensi objek aktual dan menyimpan tingkat tipuan. Tapi itu tidak akan terlihat bagus ketika ditarik dalam jawaban ini.
Ini hanyalah satu contoh implementasi. Tentu ada yang lain. Apa yang ingin ditunjukkan ini adalah bahwa semakin dekat Anda membiarkan subtipe bentuk ini tetap dengan tanggung jawab tunggal mereka, semakin baik keseluruhan sistem bekerja. Kemungkinan ada solusi yang lebih cepat dan lebih sedikit memori tetapi jika mereka memaksa saya untuk menyebarkan pengetahuan tentang subtipe di sekitar saya akan enggan menggunakannya bahkan dengan keuntungan kinerja. Saya tidak akan menggunakannya kecuali saya jelas membutuhkannya.
Pengiriman ganda
Sampai sekarang saya benar-benar mengabaikan pengiriman ganda . Saya melakukan itu karena saya bisa. Selama logika bertabrakan tidak peduli dua jenis yang bertabrakan Anda tidak membutuhkannya. Jika Anda tidak membutuhkannya, jangan gunakan itu. Jika Anda merasa mungkin membutuhkannya, tunda berurusan dengannya selama mungkin. Sikap ini disebut YAGNI .
Jika Anda memutuskan Anda benar-benar membutuhkan berbagai jenis tabrakan maka tanyakan pada diri Anda apakah n subtipe benar-benar membutuhkan 2 jenis tabrakan. Sejauh ini saya telah bekerja sangat keras untuk memudahkan menambahkan subtipe bentuk lain. Saya tidak ingin merusaknya dengan implementasi pengiriman ganda yang memaksa lingkaran mengetahui kotak ada.
Berapa banyak jenis tabrakan di sana? Sedikit berspekulasi (hal yang berbahaya) menciptakan tumbukan elastis (goyang), tidak elastis (lengket), energik (meledak), dan destruktif (rusak). Mungkin ada lebih banyak tetapi jika ini kurang dari n 2 mari kita tidak merancang tabrakan kita.
Ini berarti ketika torpedo saya mengenai sesuatu yang menerima kerusakan, ia tidak harus TAHU itu mengenai kapal ruang angkasa. Hanya harus mengatakannya, "Ha ha! Kamu mengambil 5 poin kerusakan."
Hal-hal yang menangani kerusakan mengirimkan pesan kerusakan ke hal-hal yang menerima pesan kerusakan. Dengan cara itu Anda bisa menambahkan bentuk baru tanpa memberi tahu bentuk lain tentang bentuk baru. Anda hanya akan menyebar di sekitar jenis tabrakan baru.
Kapal luar angkasa dapat mengirim kembali ke torp "Ha ha! Kau mengambil 100 poin kerusakan." dan juga "Anda sekarang terjebak di lambung kapal saya". Dan torp dapat mengirim kembali "Yah, aku sudah selesai untuk jadi lupakan aku".
Tidak ada yang tahu persis apa masing-masing. Mereka hanya tahu bagaimana berbicara satu sama lain melalui antarmuka tabrakan.
Sekarang yakin, pengiriman ganda memungkinkan Anda mengontrol hal-hal lebih intim dari ini, tetapi apakah Anda benar-benar menginginkannya ?
Jika Anda melakukannya, setidaknya pikirkan tentang melakukan pengiriman ganda melalui abstraksi jenis tabrakan apa yang diterima bentuk dan bukan pada implementasi bentuk yang sebenarnya. Juga, perilaku tabrakan adalah sesuatu yang Anda dapat menyuntikkan sebagai ketergantungan dan mendelegasikan ketergantungan itu.
Performa
Kinerja selalu penting. Tapi itu tidak berarti itu selalu menjadi masalah. Tes kinerja. Jangan hanya berspekulasi. Mengorbankan segala sesuatu atas nama kinerja biasanya tidak mengarah pada kode performen.