Saya telah mengkode selama sekitar 8 tahun, namun saya masih menemukan warisan terlalu fleksibel dan kadang-kadang membuat Anda benar-benar bingung dengan kode yang Anda tulis. Salah satu contoh paling sederhana adalah:
abstract class AClass {
protected void method1() {
if(check()) {
do1();
} else {
do2();
}
}
protected abstract void do1();
protected abstract void do2();
}
Tujuan kelas adalah agar orang dapat mengimplementasikan do1 () dan do2 () sehingga beberapa logika lebih lanjut dapat dilakukan, namun terkadang orang memutuskan untuk membebani method1 (), dan kemudian semuanya menjadi rumit dengan segera.
Saya hanya menemukan dalam pola strategi, kode digunakan kembali dengan baik melalui warisan, dalam banyak kasus perancang kelas dasar tahu subkelasnya dengan sangat baik, dan bahwa warisan sepenuhnya opsional.
Saya memiliki kelas yang diwarisi oleh 4 kelas - sebuah IoHandler, dan subclass untuk sisi server, sisi klien, server tepi, server asal, dan mulai membuat saya gila. Saya selalu dalam kode refactoring, saya selalu keluar dengan ide-ide yang saya pikir akan berhasil dan kemudian terbukti tidak. Dikatakan bahwa otak manusia hanya dapat menyimpan 7 buah informasi satu kali, apakah saya membawa terlalu banyak?
final
[jika Anda menggunakan java]. Ini secara efektif membuatnya non-virtual, dan tidak dapat kelebihan beban. Sempurna untuk digunakan dalam keadaan ini [pola templat]Jawaban:
Setelah Anda terus mengulangi pola-pola seperti itu, mereka tidak terlihat begitu rumit lagi.
Juga, Anda harus tahu tentang kelas dasar sebelum mewarisinya. Dan pewarisan tidak akan menjadi opsional selama kode umum digunakan kembali. Ambil pola lain seperti pabrik abstrak / komposit - warisan itu sebenarnya memiliki tujuan.
Aturan jempol: Jangan gunakan warisan hanya untuk menyatukan banyak kelas. Gunakan di mana pun itu masuk akal. Dalam contoh yang dibuat, pengguna kelas anak yang kelebihan metode1 harus memiliki beberapa alasan serius untuk melakukannya. (OTOH, saya juga ingin cara untuk mencegah kelebihan fungsi tertentu saja - untuk menghindari ini). Dan sebelum menggunakan kelas anak itu, Anda harus tahu tentang kekhasan ini juga. Tetapi pola strategi murni tidak akan melakukannya - jika ya, lakukan dengan sangat baik.
Jika Anda memberikan contoh kode yang sebenarnya, mungkin orang-orang di sini dapat memeriksanya untuk Anda.
sumber
Ya, ini bisa sangat rumit ... dan Anda berada di perusahaan yang baik.
Joshua Bloch di Java Efektif dengan baik menangkap beberapa masalah warisan dan merekomendasikan untuk memilih komposisi daripada warisan.
sumber
Saya pikir pertanyaan Anda terlalu kabur dan umum. Apa yang Anda gambarkan terdengar seperti masalah yang rumit, dengan atau tanpa warisan. Jadi IMHO itu sepenuhnya normal bahwa Anda berjuang dengan itu.
Tentu saja dalam beberapa kasus warisan bukan alat terbaik untuk pekerjaan (referensi wajib untuk "mendukung komposisi daripada warisan" ;-). Tetapi ketika digunakan dengan hati-hati, saya merasa itu berguna. Dari uraian Anda, sulit untuk memutuskan apakah warisan adalah alat yang tepat untuk kasus Anda.
sumber
jika metode Anda terlalu rumit, itu membuat subkelas menangis
membuat metode Anda melakukan satu hal spesifik
sumber
Warisan komposisi mempersempit vektor perubahan.
Bayangkan solusi Anda diimplementasikan dan Anda menggunakan AClass di 300 tempat berbeda dari basis kode, dan sekarang ada persyaratan untuk mengubah 45 panggilan method1 () sehingga metode do3 () dipanggil alih-alih do2 ().
Anda dapat mengimplementasikan do3 () pada IAnInterface (mudah-mudahan semua implementasi antarmuka dapat menangani metode do3 () dengan mudah) dan membuat BClass yang memanggil do1 () atau do3 () di method1 () memanggil dan mengubah referensi 45 ke baik AClass dan ketergantungan yang disuntikkan.
sekarang gambar mengimplementasikan perubahan yang sama untuk do4 (), do5 (), ...
Atau Anda bisa melakukan yang berikut ...
Sekarang Anda hanya perlu menerapkan pabrik kedua yang mengembalikan Doer1 atau Doer2 dan mengubah injeksi pabrik di 45 tempat. AClass tidak berubah, IAnInterface tidak berubah, dan Anda dapat dengan mudah menangani lebih banyak perubahan seperti do4 (), do5 ().
sumber
Kenapa tidak melakukannya:
(Saya pikir final sama dengan "disegel" dalam C #, seseorang tolong perbaiki saya jika sintaks itu salah).
Dependency injection / IoC berarti Anda hanya dapat mewarisi metode yang benar-benar Anda inginkan agar orang dapat mengubahnya, yang menurut saya menyelesaikan masalah Anda. Plus, itu tidak terdengar seperti kelas utama benar-benar melakukan apa pun do1 dan do2, lebih dari itu mendelegasikan panggilan ke subkelasnya berdasarkan pada suatu kondisi: Anda melanggar pemisahan kekhawatiran!
sumber