Apakah suatu objek ada secara fisik atau tidak, kita dapat memilih untuk memodelkannya dengan cara yang berbeda. Kita bisa secara arbiter menggunakan generalisasi atau komposisi dalam banyak kasus. Namun, prinsip GoF "mendukung komposisi daripada generalisasi [sic]" memandu kita untuk menggunakan komposisi. Jadi, ketika kita memodelkan, misalnya, sebuah garis maka kita membuat kelas yang berisi dua anggota PointA dan PointB dari tipe Point (komposisi) alih-alih memperluas Point (generalisasi). Ini hanyalah contoh sederhana tentang bagaimana kita dapat memilih komposisi atau pewarisan untuk dijadikan model, walaupun benda-benda itu biasanya jauh lebih kompleks.
Bagaimana kita tahu bahwa ini adalah pilihan yang tepat? Itu penting setidaknya karena mungkin ada satu ton refactoring yang harus dilakukan jika itu salah?
sumber
Jawaban:
Itu tidak selalu merupakan pilihan yang tepat. Ini adalah yang menguntungkan dalam banyak kasus. Ketika model komposit memerlukan perubahan atau ekstensi, itu jauh lebih tahan terhadap itu karena Anda dapat mengubah komposisi tanpa takut mempengaruhi kelas lain secara tidak sengaja.
Bagaimana kita tahu ini? Dari pengalaman, dan pengalaman orang lain.
Saya telah melihat banyak situasi di mana hirarki kelas besar telah tumbuh dari apa yang dimulai sebagai konsep sederhana, dan ini adalah di mana refactoring utama Anda menjadi perlu. Sementara itu saya belum pernah melihat situasi di mana struktur komposisi membutuhkan refactoring menjadi warisan.
Tetapi bukti anekdotal saya seharusnya tidak cukup. Lihat saja di internet dan banyak orang memiliki pengalaman yang sama.
sumber
Jika Anda ingin aturan praktis yang lebih kuat di luar "mendukung komposisi daripada warisan" maka saya mungkin menyarankan sesuatu seperti ini:
Dari dua cara untuk mengkhususkan objek - Warisan dan Komposisi - Anda harus menggunakan warisan hanya ketika Anda membutuhkan objek Anda menjadi polimorfik (dapat diganti) untuk kelas dasar yang Anda mengkhususkan.
Namun seperti semua aturan praktis, setelah Anda memahami aturan - maka Anda bebas untuk melanggar aturan :)
sumber
Saya tidak melihat bagaimana komposisi dan generalisasi adalah alternatif dan gagal menemukan kutipan .
Komposisi dan pewarisan adalah (untuk mencapai spesialisasi), dan dapat diperdebatkan, bahwa abstraksi dan generalisasi adalah (untuk mencapai modularitas).
Yang Anda inginkan adalah desain Anda sederhana dan masuk akal, yang merupakan dua kualitas yang secara inheren cukup mudah diukur.
Dalam kasus Anda, tampaknya lebih masuk akal untuk menyusun garis dua titik alih-alih memperpanjangnya, karena Anda secara alami akan menentukan garis dengan dua titik, daripada dengan memperluas konsep titik.
sumber
Favor terjadi ketika kedua kandidat lolos. Masalah yang dinyatakan dalam pertanyaan gagal pada akun ini, karena hanya memiliki opsi komposisi.
"Komposisi bisa menggunakan generalisasi juga". Apakah pernyataan ini masuk akal bagi kami? Jika tidak maka kita belum siap untuk memahami aturan 'nikmat'.
Mengapa kami lebih menyukai Komposisi adalah bahwa Komposisi menawarkan kemungkinan ekstensi / fleksibilitas lebih daripada generalisasi. Ekstensi / fleksibilitas ini sebagian besar merujuk pada runtime / fleksibilitas dinamis (yang dicapai dengan kombinasi antarmuka dan komposisi).
Manfaatnya tidak segera terlihat. Untuk melihat manfaatnya, Anda harus menunggu permintaan perubahan tak terduga berikutnya. Jadi dalam kebanyakan kasus, mereka yang berpegang pada generalisasi gagal jika dibandingkan dengan mereka yang memeluk komposisi (kecuali satu kasus yang jelas disebutkan kemudian). Karena itu aturannya. Dari sudut pandang pembelajaran jika Anda dapat mengimplementasikan injeksi ketergantungan dengan sukses maka Anda harus tahu mana yang disukai dan kapan. Aturan membantu Anda dalam membuat keputusan saat Anda tidak yakin mana yang harus dipilih. Sekali lagi Anda harus dapat melihat kedua opsi di tempat pertama untuk mendukung satu.
Ringkasan: Komposisi: Kopling dikurangi dengan hanya memiliki beberapa hal kecil yang Anda tancapkan ke sesuatu yang lebih besar, dan objek yang lebih besar hanya memanggil objek yang lebih kecil kembali. Generalisasi: Dari sudut pandang API pihak ke-3, mendefinisikan bahwa suatu metode dapat diganti adalah komitmen yang lebih kuat daripada mendefinisikan bahwa suatu metode dapat disebut (yakin menang untuk Generalisasi). Dan jangan pernah lupa bahwa dengan komposisi Anda menggunakan generalisasi juga, dari antarmuka bukan kelas besar. Namun sayangnya seluruh kredit masuk ke komposisi.
sumber
Hari ini saya menulis sekitar 300 LoC. Dan saya tidak ingat prinsip apa pun yang bisa saya langgar dan tidak dilanggar. Saya berharap Refactoring akan menyelamatkan jiwa saya.
Jika abstraksi ditentukan oleh api pihak 3d - biasanya benar menggunakan warisan. Dalam desain domestik, entitas harus abstrak atau disegel. Entitas abstrak berpotensi harus memiliki sekitar 3 pewaris. Saya tidak suka satu titik ekstensi metode-virtual. Semua di atas adalah tentang seleraku. Saya tidak berbicara tentang antarmuka abstraksi, yang melengkapi cerita berbeda.
sumber