Bayangkan situasi di mana kami menggunakan pustaka yang memungkinkan Anda membuat Circle
objek, di mana Anda dapat menentukan radius dan pusat lingkaran untuk mendefinisikannya. Namun, untuk beberapa alasan, dibutuhkan juga flavour
parameter yang diperlukan . Sekarang katakanlah saya benar-benar perlu menggunakannya Circle
di aplikasi saya sendiri, tetapi untuk keperluan aplikasi saya, saya dapat mengatur rasanya Flavours.Cardboard
setiap saat.
Untuk "memecahkan" ini, saya membuat Circle
kelas saya sendiri di namespace yang berbeda, yang hanya mengambil radius
dan center
sebagai parameter, tetapi memiliki konverter implisit ke kelas perpustakaan eksternal Circle
yang baru saja membuat Circle(this.radius, this.center, Flavours.Cardboard)
objek. Jadi di mana pun saya membutuhkan jenis lain Circle
, saya membiarkan konversi otomatis terjadi.
Apa konsekuensi dari menciptakan kelas seperti itu? Apakah ada solusi yang lebih baik? Apakah ada bedanya jika aplikasi saya adalah API yang dibangun di atas perpustakaan eksternal ini, yang dimaksudkan untuk digunakan oleh programmer lain?
sumber
MakeCircle
fungsi ?makePlayer
itu sendiri hanya menerima koordinasi untuk menempatkan pemain, tetapi mendelegasikan ke konstruktor yang jauh lebih kompleks.Jawaban:
Meskipun tidak selalu buruk, sangat jarang bahwa konversi tersirat adalah pilihan terbaik Anda.
Ada beberapa masalah.
Secara umum, ada solusi yang lebih baik.
Secara pribadi, saya menemukan # 2 menjadi yang paling sederhana untuk diimplementasikan, dan paling tidak memberatkan pada desain. Yang lain bisa baik-baik saja, mengingat situasinya dan apa lagi yang Anda coba lakukan dengan kelas-kelas ini.
Konversi implisit adalah pilihan terakhir, dan sepertinya benar-benar layak bagi saya ketika saya memiliki functor gaya C ++ yang saya coba buat - objek strategi yang secara implisit saya konversi ke tipe delegasi.
sumber
Mengingat skenario yang Anda gambarkan, Anda dapat memikirkan ini dalam hal aplikasi fungsi parsial.
Konstruktor adalah fungsi (setidaknya dalam teori; dalam C #, Anda dapat membuat "fungsi pabrik" yang memanggil konstruktor):
untuk aplikasi parsial, berikut ini sudah cukup:
Anda sekarang bisa mendapatkan konstruktor yang hanya membutuhkan 2 parameter:
Jadi sekarang Anda memiliki fungsi pabrik dengan parameter yang Anda inginkan
BTW, ini jelas setara dengan opsi 2 di atas, hanya dari perspektif yang lebih fungsional.
sumber