Bagaimana kita tahu untuk menyukai komposisi daripada generalisasi selalu merupakan pilihan yang tepat?

9

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?

CarneyCode
sumber
9
Contoh Anda tidak benar-benar berfungsi karena Anda tidak dapat mengatakan bahwa sebuah garis adalah sebuah poin, dan karena itu gagal Prinsip Pengganti Liskov dan warisan tidak tepat.
Dean Harding
@Dean: Seperti yang mungkin Anda sadari, contohnya tidak sentral ke titik. Sebagai catatan, garis dapat direpresentasikan sebagai persamaan yang didefinisikan melalui dua titik.
CarneyCode
1
@Songo: Sepertinya Anda benar-benar melewatkan intinya.
CarneyCode
Bukankah memperluas spesialisasi bukan generalisasi?
Tulains Córdova

Jawaban:

17

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.

pdr
sumber
Saya menyukainya; ambil upvote.
CarneyCode
+1 untuk "Saya belum pernah melihat situasi di mana struktur komposisi membutuhkan refactoring menjadi warisan."
Kazark
7

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 :)

Stephen Bailey
sumber
0

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.

back2dos
sumber
Apakah ini lebih alami? Garis tidak lebih dari dua poin daripada satu titik diperpanjang?
CarneyCode
2
Saya belum pernah melihat definisi garis yang tidak termasuk fakta bahwa itu dibuat dari 2+ poin. Bahkan menggunakan persamaan garis jika Anda hanya memiliki 1 x nilai dalam domain angka Anda maka itu adalah titik, bukan garis.
Rig
0

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.

Blue Clouds
sumber
-4

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.

Andrew_B
sumber