Ada tiga cara umum, AFAIK, untuk menerapkan reusability ketika datang ke OOP
- Warisan: biasanya mewakili is-a relationship (bebek is-a bird)
- Komposisi: biasanya mewakili has-a relationship (mobil memiliki-mesin)
- Ciri (mis. Kata kunci ciri dalam PHP): ... tidak terlalu yakin tentang ini
Sementara bagi saya kelihatannya sifat-sifat dapat mengimplementasikan hubungan has-a dan is-a, saya tidak begitu yakin model seperti apa yang dimaksudkan untuk itu. Situasi seperti apa yang dirancang untuk sifat-sifat itu?
object-oriented-design
Extrakun
sumber
sumber
Jawaban:
Ciri adalah cara lain untuk melakukan komposisi. Pikirkan mereka sebagai cara untuk menyusun semua bagian kelas pada waktu kompilasi (atau waktu kompilasi JIT), merakit implementasi konkret dari bagian-bagian yang akan Anda butuhkan.
Pada dasarnya, Anda ingin menggunakan ciri-ciri ketika Anda menemukan diri Anda membuat kelas dengan kombinasi fitur yang berbeda. Situasi ini muncul paling sering untuk orang-orang menulis perpustakaan fleksibel untuk dikonsumsi orang lain. Misalnya, inilah deklarasi kelas unit test yang saya tulis baru-baru ini menggunakan ScalaTest :
Kerangka uji unit memiliki banyak opsi konfigurasi yang berbeda, dan setiap tim memiliki preferensi yang berbeda tentang bagaimana mereka ingin melakukan sesuatu. Dengan menempatkan opsi-opsi ke dalam sifat-sifat (yang dicampur digunakan
with
dalam Scala), ScalaTest dapat menawarkan semua opsi tersebut tanpa harus membuat nama kelas sepertiWordSpecLikeWithMatchersAndFutures
, atau satu ton runtime boolean flag sepertiWordSpecLike(enableFutures, enableMatchers, ...)
. Ini membuatnya mudah untuk mengikuti prinsip Terbuka / tertutup . Anda dapat menambahkan fitur baru, dan kombinasi fitur baru, cukup dengan menambahkan sifat baru. Ini juga membuatnya lebih mudah untuk mengikuti Prinsip Segregasi Antarmuka , karena Anda dapat dengan mudah memasukkan fungsi yang tidak diperlukan secara universal ke dalam suatu sifat.Ciri juga merupakan cara yang baik untuk meletakkan kode umum ke beberapa kelas yang tidak masuk akal untuk berbagi hierarki warisan. Warisan adalah hubungan yang sangat erat, dan Anda tidak harus membayar biaya itu jika Anda dapat membantunya. Ciri-ciri adalah hubungan yang jauh lebih longgar. Dalam contoh saya di atas, saya biasa
MyCustomTrait
dengan mudah berbagi implementasi database tiruan antara beberapa kelas tes yang tidak terkait.Ketergantungan injeksi mencapai banyak tujuan yang sama, tetapi pada saat runtime berdasarkan input pengguna dan bukan pada waktu kompilasi berdasarkan input programmer. Ciri juga lebih ditujukan untuk dependensi yang secara semantik bagian dari kelas yang sama. Anda semacam merakit bagian-bagian dari satu kelas daripada menelepon ke kelas lain dengan tanggung jawab lain.
Kerangka kerja injeksi ketergantungan mencapai banyak tujuan yang sama pada waktu kompilasi berdasarkan input programmer, tetapi sebagian besar merupakan solusi untuk bahasa pemrograman tanpa dukungan sifat yang tepat. Ciri membawa dependensi ini ke dalam bidang pemeriksa tipe kompiler, dengan sintaks yang lebih bersih, dengan proses pembuatan yang lebih sederhana, yang membuat perbedaan yang lebih jelas antara dependensi waktu kompilasi dan runtime.
sumber
with
operator adalah apa yang membedakan mereka, danwith
adalah operasi komposisi. Dan ya, sifat-sifat menggantikan DI tanpa harus didefinisikan pada titik masuk kode. Itulah salah satu hal yang membuat mereka lebih disukai menurut saya.