Saya refactoring situs web warisan PHP OOP.
Saya sangat tergoda untuk mulai menggunakan 'final' di kelas untuk " make it explicit that the class is currently not extended by anything
". Ini mungkin menghemat banyak waktu jika saya datang ke kelas dan saya bertanya-tanya apakah saya dapat mengganti nama / menghapus / memodifikasi protected
properti atau metode. Jika saya benar - benar ingin memperluas kelas saya hanya dapat menghapus kata kunci terakhir untuk membukanya untuk diperpanjang.
Yaitu Jika saya datang ke kelas yang tidak memiliki kelas anak saya dapat mencatat pengetahuan itu dengan menandai kelas sebagai final. Lain kali saya datang ke sana saya tidak perlu mencari kembali basis kode untuk melihat apakah ada anak-anak. Sehingga menghemat waktu saat refactorings.
Itu semua sepertinya ide hemat waktu yang masuk akal .... tapi saya sering membaca bahwa kelas hanya boleh dibuat 'final' pada kesempatan langka / khusus.
Mungkin itu mengacaukan pembuatan objek Mock atau memiliki efek samping lain yang tidak saya pikirkan.
Apa yang saya lewatkan?
sumber
Jawaban:
Siapa pun yang menulis itu salah. Gunakan dengan
final
bebas, tidak ada yang salah dengan itu. Ini mendokumentasikan bahwa kelas tidak dirancang dengan mempertimbangkan warisan, dan ini biasanya berlaku untuk semua kelas secara default: merancang kelas yang dapat diwarisi secara bermakna membutuhkan lebih dari sekadar menghapusfinal
specifier; itu membutuhkan banyak perawatan.Jadi menggunakan
final
secara default sama sekali tidak buruk. Bahkan, banyak orang mengusulkan bahwa ini harus menjadi default, misalnya Jon Skeet .Ini memang peringatan, tetapi Anda selalu bisa menggunakan antarmuka jika Anda perlu mengejek kelas Anda. Ini tentu saja lebih unggul daripada membuat semua kelas terbuka untuk warisan hanya untuk tujuan mengejek.
sumber
final
akan memainkan peran yang jauh lebih besar.Jika Anda ingin meninggalkan catatan untuk diri sendiri bahwa suatu kelas tidak memiliki sub-kelas, maka dengan segala cara melakukannya dan menggunakan komentar, itulah gunanya. Kata kunci "final" bukan komentar, dan menggunakan kata kunci bahasa hanya untuk memberi sinyal sesuatu kepada Anda (dan hanya Anda yang akan tahu apa artinya) adalah ide yang buruk.
sumber
final
seperti yang diharapkan. Tidak ada yang salah dengan itu. Dan menggunakan fitur bahasa untuk menegakkan kendala selalu lebih baik daripada menggunakan komentar.final
harus menyatakan "Tidak boleh ada subclass dari kelas ini yang dibuat" (untuk alasan hukum atau sesuatu), bukan "kelas ini saat ini tidak memiliki anak, jadi saya masih aman untuk mengacaukan dengan anggota yang dilindungi". Maksudnyafinal
adalah kebalikan dari "diedit secara bebas", dan sebuahfinal
kelas bahkan tidak boleh memilikiprotected
anggota!final
berarti, “kelas ini tidak diperpanjang [untuk saat ini].” Tidak lebih, tidak kurang. Apakah PHP dirancang dengan filosofi ini dalam pikiran adalah tidak relevan: ia memiliki satufinal
kata kunci, setelah semua. Kedua, berdebat dari desain PHP pasti gagal, mengingat bagaimana patchworky dan hanya keseluruhan PHP yang buruk dirancang.Ada artikel yang bagus tentang "Kapan mendeklarasikan kelas final" . Beberapa kutipan darinya:
PS Terima kasih kepada @ocramius untuk bacaan yang bagus!
sumber
"final" untuk suatu kelas berarti: Anda menginginkan subkelas? Silakan, hapus "final", subklas sebanyak yang Anda suka, tapi jangan mengeluh kepada saya jika itu tidak berhasil. Anda sendirian.
Ketika sebuah kelas dapat disubklasifikasikan, itu perilaku yang diandalkan orang lain, harus dijelaskan dalam istilah abstrak yang dipatuhi subkelas. Penelepon harus ditulis untuk mengharapkan beberapa variasi. Dokumentasi harus ditulis dengan cermat; Anda tidak dapat memberi tahu orang "lihat kode sumber" karena kode sumbernya belum ada. Itu semua usaha. Jika saya tidak berharap bahwa sebuah kelas subkelas, itu adalah upaya yang tidak perlu. "Final" dengan jelas mengatakan bahwa upaya ini belum dilakukan dan memberikan peringatan yang adil.
sumber
Satu hal yang Anda mungkin tidak pikirkan adalah kenyataan bahwa setiap perubahan kelas berarti bahwa ia harus menjalani pengujian QA baru.
Jangan menandai hal-hal sebagai final kecuali Anda benar-benar bersungguh-sungguh.
sumber
final
(perubahan) maka saya hanya perlu mengujinya kembali?final
. Apakah ini pengalaman langsung?final
Kelas memiliki satu kasus penggunaan utama. Anda memiliki kelas polimorfik yang tidak ingin diperpanjang karena subkelas dapat merusak polimorfisme. Jangan gunakanfinal
kecuali Anda harus mencegah pembuatan subclass. Selain itu, tidak ada gunanya.Menggunakan 'final' menghilangkan kebebasan orang lain yang ingin menggunakan kode Anda.
Jika kode yang Anda tulis hanya untuk Anda dan tidak akan pernah dirilis ke publik atau pelanggan, maka Anda dapat melakukannya dengan kode yang Anda inginkan, tentu saja. Kalau tidak, Anda mencegah orang lain membuat kode Anda. Terlalu sering saya harus bekerja dengan API yang akan mudah diperluas untuk kebutuhan saya, tetapi kemudian saya terhalang oleh 'final'.
Juga, sering ada kode yang sebaiknya tidak dibuat
private
, tetapiprotected
. Tentu,private
berarti "enkapsulasi" dan menyembunyikan hal-hal yang dianggap sebagai detail implementasi. Tetapi sebagai seorang programmer API saya mungkin juga mendokumentasikan fakta bahwa metodexyz
dianggap sebagai detail implementasi dan, dengan demikian, dapat diubah / dihapus dalam versi yang akan datang. Jadi setiap orang yang akan bergantung pada kode tersebut terlepas dari peringatan melakukannya dengan risiko sendiri. Tapi dia benar-benar dapat melakukannya dan menggunakan kembali (semoga sudah diuji) kode dan muncul lebih cepat dengan solusi.Tentu saja, jika implementasi API adalah open source, Anda hanya dapat menghapus metode 'final' atau membuat 'terlindungi', tetapi daripada Anda telah mengubah kode dan perlu melacak perubahan Anda dalam bentuk tambalan.
Namun, jika penerapannya adalah sumber tertutup, Anda akan tertinggal dalam menemukan solusi atau, dalam kasus terburuk, dengan beralih ke API lain dengan sedikit pembatasan mengenai kemungkinan untuk kustomisasi / ekstensi.
Perhatikan bahwa saya tidak menemukan 'final' atau 'pribadi' itu jahat, tetapi saya pikir mereka terlalu sering digunakan karena programmer tidak memikirkan kode-nya dalam hal penggunaan kembali dan ekstensi kode.
sumber