Saya telah pemrograman dalam bahasa prosedural untuk beberapa waktu sekarang, dan reaksi pertama saya terhadap masalah adalah mulai memecahnya menjadi tugas untuk dilakukan daripada mempertimbangkan entitas yang berbeda (objek) yang ada dan hubungan mereka.
Saya telah mengikuti kursus universitas di OOP, dan memahami dasar-dasar enkapsulasi, abstraksi data, polimorfisme, modularitas, dan pewarisan.
Saya membaca /programming/2688910/learning-to-think-in-the-object-oriented-way dan /programming/1157847/learning-object-oriented-thinking , dan akan melihat beberapa buku yang ditunjukkan dalam jawaban itu.
Saya pikir beberapa proyek saya yang berukuran sedang hingga besar akan mendapat manfaat dari penggunaan OOP yang efektif, tetapi sebagai pemula saya ingin menghindari kesalahan umum yang memakan waktu.
Berdasarkan pengalaman Anda, apa saja jebakan ini dan apa cara yang masuk akal di sekitar mereka? Jika Anda bisa menjelaskan mengapa itu adalah jebakan, dan bagaimana saran Anda efektif dalam mengatasi masalah itu akan dihargai.
Saya berpikir seperti "Apakah biasa memiliki cukup banyak metode pengamat dan pengubah dan menggunakan variabel pribadi atau apakah ada teknik untuk mengkonsolidasikan / menguranginya?"
Saya tidak khawatir tentang menggunakan C ++ sebagai bahasa OO murni, jika ada alasan yang baik untuk mencampur metode. (Mengingatkan alasan untuk menggunakan GOTO, meskipun hemat.)
Terima kasih!
sumber
Jawaban:
Satu hal besar yang saya pelajari adalah merancang kelas dari luar. Rancang antarmuka sebelum Anda mulai berpikir tentang implementasinya. Ini akan membuat kelas jauh, lebih intuitif untuk pengguna Anda (mereka yang menggunakan kelas) daripada menulis algoritma yang mendasari dan membangun kelas, dan menulis fungsi anggota publik baru sesuai kebutuhan.
sumber
Ya, yang pertama adalah perangkap mengungkapkan terlalu banyak informasi. Defaultnya seharusnya
private
, bukanpublic
.Setelah itu muncul terlalu banyak getter / setter. Katakanlah saya memiliki anggota data. Apakah saya benar - benar membutuhkan data ini di kelas lain? Ok, buat pengambil. Apakah saya benar-benar perlu mengubah data ini selama umur objek? Lalu buat setter.
Kebanyakan programmer pemula memiliki default untuk membuat pengambil / penyetel untuk setiap anggota data. Ini berantakan antarmuka dan sering merupakan pilihan desain yang buruk.
sumber
Ketika saya melewati jurang itu, saya memutuskan pendekatan berikut:
0) Saya mulai lambat, dengan aplikasi prosedural ukuran kecil / menengah, dan tidak ada hal penting di tempat kerja.
1) pemetaan 1st-pass sederhana tentang bagaimana saya akan menulis program dari awal dengan gaya OO - yang paling penting bagi saya pada waktu itu, dan ini subyektif IS - adalah untuk mengetahui semua kelas dasar. Objek saya adalah merangkum sebanyak mungkin di kelas dasar. Metode virtual murni untuk segala yang mungkin terjadi di kelas dasar.
2) Kemudian langkah selanjutnya adalah membuat derivasi.
3) langkah terakhir adalah - dalam kode prosedur asli, pisahkan struktur data dari kode pengamat / pengubah. Kemudian gunakan menyembunyikan data dan memetakan semua data umum ke dalam kelas dasar, dan dalam subkelas pergi data yang tidak umum di seluruh program. Dan perlakuan yang sama untuk pengamat prosedural / kode pengubah - semua logika 'digunakan di mana saja' masuk ke kelas dasar. Dan melihat / memodifikasi logika yang hanya bertindak pada sebagian data masuk ke kelas turunan.
Ini subjektif tetapi FAST, jika Anda tahu kode prosedural dan struktur data dengan baik. GAGAL dalam tinjauan kode adalah ketika sedikit data atau logika tidak muncul di kelas dasar tetapi digunakan di mana-mana.
sumber
Lihatlah proyek sukses lainnya yang menggunakan OOP untuk mendapatkan kesan gaya yang baik. Saya merekomendasikan untuk melihat Qt , sebuah proyek yang selalu saya perhatikan ketika membuat keputusan desain sendiri.
sumber
Bergantung pada siapa Anda berbicara, semua data dalam OOP harus pribadi atau dilindungi, dan hanya tersedia melalui pengakses dan mutator. Secara umum, saya pikir ini adalah praktik yang baik, tetapi ada beberapa kesempatan di mana saya menyimpang dari norma ini. Sebagai contoh, jika Anda memiliki kelas (di Jawa, katakanlah) yang tujuannya hanya untuk memasukkan beberapa bagian data ke dalam unit logis, masuk akal untuk membiarkan bidang publik. Jika itu adalah kapsul yang tidak dapat diubah, tandai saja mereka sudah final dan inisialisasi mereka di konstruktor. Ini mengurangi kelas (dalam hal ini) menjadi sedikit lebih dari sebuah struct (pada kenyataannya, menggunakan C ++, Anda harus benar-benar menyebutnya sebagai struct. Bekerja seperti sebuah kelas, tetapi visibilitas default adalah publik, dan maksud Anda lebih jelas), tetapi Saya pikir Anda akan menemukan bahwa menggunakannya jauh lebih nyaman dalam kasus ini.
Satu hal yang pasti tidak ingin Anda lakukan adalah memiliki bidang yang harus diperiksa untuk konsistensi dalam mutator, dan biarkan publik.
sumber
struct
s - itu tidak membuat perbedaan semantik, tetapi itu menjelaskan maksudnya, dan membuat penggunaannya tampak lebih alami, terutama untuk programmer C.Buku Implementasi Kent Beck adalah landasan yang sangat baik dalam cara menggunakan, bukan menyalahgunakan, mekanisme berorientasi objek.
sumber
Saya tidak khawatir tentang menggunakan C ++ sebagai bahasa OO murni, jika ada alasan yang baik untuk mencampur metode. (Mengingatkan alasan untuk menggunakan GOTO, meskipun hemat.)
Saya tidak benar-benar berpikir saya punya banyak untuk menawarkan percakapan sampai saya melihat ini sedikit. Saya harus tidak setuju dengan sentimen. OOP hanyalah salah satu dari paradigma yang dapat dan harus digunakan dalam C ++. Terus terang, menurut saya itu bukan salah satu fitur terkuatnya.
Dari sudut pandang OO saya pikir C ++ sebenarnya jatuh agak pendek. Gagasan memiliki fungsi non-virtual misalnya adalah tanda centang dalam hal ini. Saya memiliki argumen dengan mereka yang tidak setuju dengan saya, tetapi anggota non-virtual tidak cocok dengan paradigma sejauh yang saya ketahui. Polimorfisme adalah komponen kunci untuk OO dan kelas-kelas dengan fungsi non-virtual bukanlah polimorfik dalam arti OO. Jadi sebagai bahasa OO saya pikir C ++ sebenarnya agak lemah jika dibandingkan dengan bahasa seperti Java atau Objective-C.
Pemrograman generik di sisi lain, C ++ memiliki yang satu ini cukup bagus. Saya pernah mendengar bahwa ada bahasa yang lebih baik untuk ini, tetapi kombinasi objek dan fungsi generik adalah sesuatu yang cukup kuat dan ekspresif. Selain itu dapat sangat cepat baik dalam waktu pemrograman dan waktu pemrosesan. Ini benar-benar di daerah ini yang saya pikir C ++ bersinar meskipun diakui itu bisa lebih baik (dukungan bahasa untuk konsep misalnya). Seseorang yang berpikir bahwa mereka harus berpegang teguh pada paradigma OO dan memperlakukan yang lain pada urutan pernyataan kebohongan dalam tingkat amoralitas benar-benar hilang dengan tidak melihat paradigma ini.
Kapasitas metaprogramming template juga cukup mengesankan. Lihat perpustakaan Boost.Units misalnya. Perpustakaan ini menyediakan dukungan tipe untuk jumlah dimensi. Saya telah memanfaatkan perpustakaan ini secara ekstensif di perusahaan teknik tempat saya bekerja saat ini. Ini hanya memberikan umpan balik yang jauh lebih cepat untuk satu aspek dari programmer yang mungkin, atau bahkan kesalahan spesifikasi. Tidak mungkin mengkompilasi program yang menggunakan rumus di mana kedua sisi operator '=' tidak setara secara dimensi tanpa casting eksplisit. Saya pribadi tidak punya pengalaman dengan bahasa lain di mana ini mungkin, dan tentu saja tidak dengan bahasa yang juga memiliki kekuatan dan kecepatan C ++.
Metaprogramming adalah paradigma yang murni fungsional.
Jadi sungguh, saya pikir Anda sudah melangkah ke C ++ dengan beberapa kesalahpahaman yang disayangkan. Paradigma lain selain OO tidak harus dihindari, mereka harus LEVERAGED. Gunakan paradigma yang wajar untuk aspek masalah yang sedang Anda kerjakan. Jangan memaksakan objek pada apa yang pada dasarnya bukan masalah rawan objek. Sejauh yang saya ketahui, OO bahkan tidak setengah cerita untuk C ++.
sumber
Saya ingin menerima jawaban untuk pertanyaan ini, tetapi saya tidak dapat memutuskan satu jawaban untuk melimpahkan tanda centang. Karena itu saya telah mengangkat penulis asli dan membuat ini sebagai jawaban ringkasan. Terima kasih kepada semua orang yang meluangkan waktu beberapa menit, saya menemukan bahwa wawasan yang Anda berikan memberi saya arahan yang baik dan sedikit kepastian bahwa saya tidak keluar dari jalur.
@ nightcracker
Saya merasa bahwa saya telah mengamati masalah ini di masa lalu. Komentar Anda membuat saya juga ingat bahwa dengan menyembunyikan variabel yang mendasarinya dan implementasinya, saya bebas untuk mengubah implementasinya tanpa merusak apa pun yang bergantung padanya.
Dominic Gurto
Saya pikir komentar Dominic adalah cita-cita yang bagus untuk dicita-citakan, tetapi saya pikir komentar Gene benar-benar menyentuh kenyataan situasi. Sejauh ini saya sudah melihat ini dalam aksi ... dan merasa sedikit lebih baik bahwa itu tidak biasa. Saya pikir bahwa ketika saya dewasa sebagai programmer saya akan condong ke arah desain yang lebih lengkap, tetapi sekarang saya masih menderita melompat dan mendapatkan beberapa kode yang ditulis-itis.
wantTheBest
Ini sangat masuk akal ... Saya menyukai gagasan menjaga hal-hal bekerja di tempat kerja, tetapi untuk memperbaiki beberapa hal yang tidak kritis dengan kelas.
jpm
Saya sudah tahu sebentar bahwa ini adalah salah satu kekuatan merangkum data ... mampu menegakkan konsistensi dan dalam hal ini kondisi / rentang / dll.
Eddie yang gila
Saya awalnya sangat merindukan jawaban Crazy Eddie, saya pikir karena saya belum membaca beberapa topik yang disebutkan ... seperti metaprogramming. Saya pikir pesan besar dalam posting CE adalah bahwa C ++ adalah perpaduan antara kemampuan dan gaya yang masing-masing harus digunakan untuk potensi terbaik mereka ... termasuk keharusan jika itu yang masuk akal.
Jadi sekali lagi, terima kasih kepada semua orang yang merespons!
sumber
Jebakan terbesar adalah keyakinan bahwa OOP adalah peluru perak, atau "satu paradigma sempurna."
sumber