it-swarm-id.com

Mengapa OOP sulit?

Ketika saya mulai menggunakan bahasa berorientasi objek (Java), saya cukup banyak hanya pergi "Keren" dan mulai coding. Saya tidak pernah benar-benar memikirkannya sampai baru-baru ini setelah membaca banyak pertanyaan tentang OOP. Kesan umum yang saya dapatkan adalah orang-orang bergumul dengannya. Karena saya belum menganggapnya susah, dan saya tidak akan mengatakan saya jenius, saya berpikir bahwa saya pasti melewatkan sesuatu atau salah paham.

Mengapa OOP sulit dipahami? Apakah sulit untuk dipahami?

93
gablin

Saya pribadi menemukan mekanisme OOP cukup mudah untuk dipahami. Bagian yang sulit bagi saya adalah "mengapa" itu. Ketika saya pertama kali terkena itu, sepertinya solusi untuk mencari masalah. Berikut adalah beberapa alasan mengapa saya pikir kebanyakan orang merasa sulit:

  1. Pengajaran IMHO OO sejak awal adalah ide yang buruk. Pengkodean prosedural bukan "kebiasaan buruk" dan merupakan alat yang tepat untuk beberapa pekerjaan. Metode individual dalam program OO cenderung terlihat cukup prosedural. Selain itu, sebelum mempelajari pemrograman prosedural dengan cukup baik sehingga keterbatasannya dapat terlihat, OO tampaknya tidak terlalu berguna bagi siswa.

  2. Sebelum Anda benar-benar dapat memahami OO, Anda perlu mengetahui dasar-dasar struktur data dan fungsi pengikatan/keteraturan yang lebih tinggi. Sulit untuk grok polimorfisme (yang pada dasarnya meneruskan pointer ke data dan banyak fungsi yang beroperasi pada data) jika Anda bahkan tidak memahami konsep penataan data, bukan hanya menggunakan primitif dan melewati fungsi urutan tinggi/pointer ke fungsi.

  3. Pola desain harus diajarkan sebagai sesuatu yang mendasar bagi OO, bukan sesuatu yang lebih maju. Pola desain membantu Anda melihat hutan melalui pepohonan dan memberikan contoh yang relatif konkret tentang di mana OO dapat menyederhanakan masalah nyata, dan bagaimanapun juga Anda ingin mempelajarinya. Selain itu, begitu Anda benar-benar mendapatkan OO, sebagian besar pola desain menjadi jelas di belakang.

120
dsimcha

Saya pikir ada beberapa faktor yang belum disebutkan.

Pertama-tama, setidaknya dalam "OOP murni" (mis., Smalltalk) di mana semuanya adalah objek, Anda harus memutar pikiran Anda menjadi konfigurasi yang agak tidak wajar untuk memikirkan angka (hanya untuk satu contoh ) sebagai objek cerdas, bukan hanya nilai - karena dalam kenyataannya, 21 (misalnya) benar-benar is hanya sebuah nilai. Ini menjadi sangat bermasalah ketika di satu sisi Anda diberitahu bahwa keuntungan besar dari OOP adalah memodelkan kenyataan lebih dekat, tetapi Anda memulai dengan mengambil apa yang tampak sangat buruk seperti tampilan yang terinspirasi LSD) bahkan bagian yang paling dasar dan jelas dari kenyataan.

Kedua, pewarisan dalam OOP juga tidak mengikuti model mental kebanyakan orang. Bagi kebanyakan orang, mengklasifikasi hal-hal yang paling spesifik tidak memiliki hampir semua aturan absolut diperlukan untuk membuat hierarki kelas yang berfungsi. Khususnya, membuat class D yang mewarisi dari yang lain class B berarti objek dari class D bagikan secara absolut, positif semua karakteristik class B. class D dapat menambahkan karakteristik baru dan berbeda sendiri, tetapi semua karakteristik class B harus tetap utuh.

Sebaliknya, ketika orang mengklasifikasikan sesuatu secara mental, mereka biasanya mengikuti model yang jauh lebih longgar. Sebagai contoh, jika seseorang membuat aturan tentang apa yang merupakan kelas objek, itu cukup khas bahwa hampir semua aturan dapat dilanggar selama cukup banyak aturan lain yang diikuti. Bahkan beberapa aturan yang tidak bisa benar-benar dilanggar hampir selalu bisa "ditarik" sedikit pula.

Sebagai contoh, pertimbangkan "mobil" sebagai kelas. Sangat mudah untuk melihat bahwa luas mayoritas dari apa yang kebanyakan orang pikirkan sebagai "mobil" memiliki empat roda. Namun, kebanyakan orang telah melihat (setidaknya gambar) mobil dengan hanya tiga roda. Beberapa dari kita dari usia yang tepat juga ingat satu atau dua mobil balap dari awal 80-an (atau lebih) yang memiliki enam roda - dan seterusnya. Ini membuat kita pada dasarnya tiga pilihan:

  1. Jangan nyatakan apa pun tentang berapa banyak roda yang dimiliki mobil - tetapi ini cenderung mengarah pada asumsi tersirat bahwa itu akan selalu 4, dan kode yang kemungkinan akan rusak untuk nomor lain.
  2. Tegaskan bahwa semua mobil memiliki empat roda, dan hanya mengklasifikasikan yang lain sebagai "bukan mobil" meskipun kita tahu sebenarnya.
  3. Rancang kelas untuk memungkinkan variasi dalam jumlah roda, untuk jaga-jaga, meskipun ada kemungkinan bagus kemampuan ini tidak akan pernah diperlukan, digunakan, atau diuji dengan benar.

Mengajar tentang OOP sering berfokus pada membangun taksonomi besar - misalnya, potongan-potongan dari apa yang akan menjadi hierarki raksasa dari semua kehidupan yang dikenal di bumi, atau sesuatu dalam urutan itu. Ini menimbulkan dua masalah: pertama dan terutama, cenderung mengarahkan banyak orang untuk fokus pada sejumlah besar informasi yang sama sekali tidak relevan dengan pertanyaan yang ada. Pada satu titik saya melihat diskusi yang agak panjang tentang bagaimana memodelkan jenis anjing, dan apakah (misalnya) " pudel miniatur "harus mewarisi dari" pudel ukuran penuh ", atau sebaliknya, atau apakah harus ada pangkalan abstrak" Pudel "kelas, dengan" pudel ukuran penuh "dan" pudel miniatur "keduanya mewarisi dari itu. Apa yang mereka semua tampak untuk diabaikan adalah bahwa aplikasi itu seharusnya berurusan dengan melacak lisensi untuk anjing, dan untuk tujuan itu sepenuhnya cukup untuk memiliki satu bidang bernama "berkembang biak" (atau sesuatu pada urutan itu) tanpa model hubungan antara keturunan sama sekali.

Kedua, dan hampir penting, ini mengarah ke fokus pada karakteristik item, daripada berfokus pada karakteristik yang penting untuk tugas yang dihadapi. Ini mengarah ke pemodelan hal-hal seperti apa adanya, di mana (sebagian besar waktu) yang benar-benar dibutuhkan adalah membangun model paling sederhana yang akan memenuhi kebutuhan kita, dan menggunakan abstraksi agar sesuai dengan perl sub-kelas agar sesuai dengan abstraksi yang kami bangun.

Akhirnya, saya akan mengatakan sekali lagi: kita perlahan mengikuti jalur yang sama yang diambil oleh database selama bertahun-tahun. Database awal mengikuti model hirarkis. Selain berfokus secara eksklusif pada data, ini adalah warisan tunggal. Untuk waktu yang singkat, beberapa basis data mengikuti model jaringan - pada dasarnya identik dengan pewarisan berganda (dan dilihat dari sudut ini, beberapa antarmuka tidak cukup berbeda dari beberapa kelas dasar untuk diperhatikan atau diperhatikan).

Dulu, bagaimanapun, basis data sebagian besar bertemu pada model relasional (dan meskipun mereka bukan SQL, pada tingkat abstraksi ini, basis data "NoSQL" saat ini juga bersifat relasional). Keuntungan dari model relasional sudah cukup terkenal sehingga saya tidak akan repot mengulanginya di sini. Saya hanya akan mencatat bahwa analog terdekat dari model relasional yang kita miliki dalam pemrograman adalah pemrograman generik (dan maaf, tetapi terlepas dari namanya, Java generik, misalnya, tidak benar-benar memenuhi syarat) , meskipun mereka adalah langkah kecil ke arah yang benar).

57
Jerry Coffin

OOP membutuhkan kemampuan untuk berpikir secara abstrak; hadiah/kutukan yang benar-benar dimiliki oleh beberapa orang, bahkan programmer profesional.

26
John Kraft

Paradigma apa pun membutuhkan dorongan "over the Edge" untuk dipahami, bagi kebanyakan orang. Menurut definisi, ini adalah cara berpikir yang baru dan oleh karena itu diperlukan sejumlah pelepasan gagasan lama dan sejumlah pemahaman sepenuhnya mengapa gagasan baru ini berguna.

Saya pikir banyak masalahnya adalah metode yang digunakan untuk mengajar pemrograman komputer secara umum sangat buruk. OOP sangat umum sekarang sehingga tidak terlihat, tetapi Anda masih sering melihatnya dalam pemrograman fungsional:

  • konsep-konsep penting tersembunyi di balik nama-nama aneh (FP: Apa itu monad? OOP: Mengapa mereka menyebutnya fungsi kadang-kadang dan metode lain kali?)

  • konsep aneh dijelaskan dalam metafora alih-alih dalam hal apa yang sebenarnya mereka lakukan, atau mengapa Anda akan menggunakannya, atau mengapa ada orang yang berpikir untuk menggunakannya (FP: Monad adalah pakaian antariksa, itu membungkus beberapa kode. OOP: An objek seperti bebek, dapat membuat suara, berjalan dan mewarisi dari Hewan)

  • hal-hal yang baik bervariasi dari orang ke orang, jadi tidak jelas apa yang akan menjadi titik kritis bagi siswa mana pun, dan seringkali guru bahkan tidak dapat mengingatnya. (FP: Oh, monad membiarkan Anda menyembunyikan sesuatu dalam tipe itu sendiri dan meneruskannya tanpa harus secara eksplisit menuliskan apa yang terjadi setiap kali. OOP: Oh, objek memungkinkan Anda menyimpan fungsi untuk jenis data dengan data itu.)

Yang terburuk adalah bahwa, seperti yang ditunjukkan oleh pertanyaan, beberapa orang akan segera mengerti mengapa konsep itu baik, dan beberapa tidak. Itu benar-benar tergantung pada apa titik kritisnya. Bagi saya, memahami bahwa objek menyimpan data dan metode untuk data itu adalah kuncinya, setelah itu segala sesuatu yang lain hanya cocok sebagai ekstensi alami. Kemudian saya kemudian melompat seperti menyadari bahwa pemanggilan metode dari suatu objek sangat mirip dengan membuat panggilan statis dengan objek itu sebagai parameter pertama.

Lompatan kecil di kemudian hari membantu memperbaiki pemahaman, tetapi yang pertama membutuhkan seseorang dari "OOP tidak masuk akal, mengapa orang melakukan ini?" untuk "OOP adalah yang terbaik, mengapa orang melakukan hal lain?"

21
CodexArcanum

Saya pikir Anda dapat merangkum kesulitan dasar dengan cara ini:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Tentu, orang bisa terbiasa dengan pemetaan "kiri" sebagai 270, dan ya, mengatakan "Mobil. Hidupkan" alih-alih "putar mobil" bukan lompatan besar. TETAPI, untuk menangani benda-benda ini dengan baik dan menciptakannya, Anda harus membalikkan cara berpikir Anda yang biasanya.

Alih-alih memanipulasi objek, kami memberi tahu objek untuk benar-benar melakukan sesuatu sendiri. Ini mungkin tidak terasa sulit lagi, tetapi mengatakan jendela untuk membuka sendiri terdengar aneh. Orang-orang yang tidak terbiasa dengan cara berpikir seperti ini harus berjuang dengan keanehan itu berulang sampai akhirnya entah bagaimana menjadi alami.

21
John Fisher

Karena penjelasan dasar dari OOP memiliki sangat, sangat sedikit hubungannya dengan bagaimana itu digunakan di lapangan. Sebagian besar program untuk mengajar itu mencoba menggunakan model fisik, seperti "Pikirkan mobil sebagai sebuah objek, dan roda sebagai objek, dan pintu, dan transmisi ... ", tetapi di luar beberapa kasus pemrograman simulasi yang tidak jelas, objek jauh lebih sering digunakan untuk mewakili konsep non-fisik atau untuk memperkenalkan tipuan. Efeknya adalah bahwa itu membuat orang memahaminya secara intuitif dengan cara yang salah.

Mengajar dari pola desain adalah cara yang jauh lebih baik untuk menggambarkan OOP, karena menunjukkan kepada pemrogram bagaimana beberapa masalah pemodelan aktual dapat secara efektif diserang dengan objek, daripada menggambarkannya secara abstrak.

15
Dan Monego

Saya tidak setuju dengan jawaban dsimcha untuk sebagian besar:

  1. Mengajar OO dari awal sebenarnya bukan ide yang buruk dalam dirinya sendiri, juga tidak mengajarkan bahasa prosedural. Yang penting adalah bahwa kita mengajar orang untuk menulis kode kohesif yang jelas, ringkas, kohesif, terlepas dari OO atau prosedural.

  2. Metode individual dalam program OO yang baik JANGAN cenderung tidak prosedural sama sekali. Ini semakin benar dengan evolusi bahasa OO bahasa (baca C # karena selain C++ itulah satu-satunya OO bahasa lainnya yang saya tahu) dan sintaksisnya yang semakin kompleks dari hari ke hari (lambdas, LINQ ke objek, dll.). Satu-satunya kesamaan antara OO metode dan prosedur dalam bahasa prosedural adalah sifat linear masing-masing, yang saya ragu akan berubah dalam waktu dekat.

  3. Anda tidak dapat menguasai bahasa prosedural tanpa memahami struktur data. Konsep pointer sama pentingnya untuk bahasa prosedural seperti untuk bahasa OO. Melewati parameter dengan referensi, misalnya, yang cukup umum dalam bahasa prosedural, mengharuskan Anda untuk memahami pointer sebanyak yang diperlukan untuk pelajari bahasa apa pun OO.

  4. Saya tidak berpikir bahwa pola desain harus diajarkan di awal OO pemrograman sama sekali, karena mereka tidak mendasar untuk pemrograman OO sama sekali. Kita pasti bisa jadilah programmer yang baik OO tanpa mengetahui apapun tentang pola desain. Bahkan seseorang bahkan dapat menggunakan pola desain yang terkenal tanpa mengetahui bahwa mereka didokumentasikan seperti itu dengan nama yang tepat dan bahwa buku-buku adalah menulis tentang mereka. Apa yang harus diajarkan secara mendasar adalah prinsip-prinsip desain seperti Tanggung Jawab Tunggal, Buka Tutup, dan Segregasi Antarmuka. Sayangnya, banyak orang yang menganggap diri mereka OO programmer saat ini tidak mengenal hal ini dengan baik) konsep fundamental atau hanya memilih untuk mengabaikannya dan itulah sebabnya kami memiliki begitu banyak sampah OO kode di luar sana. Hanya setelah pemahaman yang menyeluruh tentang ini dan prinsip-prinsip lain harus pola desain diperkenalkan.

Untuk menjawab pertanyaan poster asli, ya, OO adalah konsep yang lebih sulit untuk dipahami daripada pemrograman prosedural. Ini karena kita tidak berpikir dalam hal sifat dan metode objek kehidupan nyata. Misalnya, manusia Otak tidak siap menganggap "TurnOn" sebagai metode TV, tetapi melihatnya sebagai fungsi memutar manusia di TV. Demikian pula, polimorfisme adalah konsep asing bagi otak manusia yang umumnya melihat setiap objek kehidupan nyata hanya dengan satu " wajah ". Warisan lagi tidak alami bagi otak kita. Hanya karena saya seorang pengembang tidak berarti bahwa anak saya akan menjadi satu. Secara umum, otak manusia perlu dilatih untuk belajar OO sementara bahasa prosedural lebih alami.

13

Saya pikir banyak programmer mengalami kesulitan dengan desain dimuka dan perencanaan untuk memulai. Bahkan jika seseorang melakukan semua desain untuk Anda, masih mungkin untuk melepaskan diri dari prinsip OOP. Jika saya mengambil banyak kode spageti dan membuangnya ke dalam kelas, apakah itu benar-benar OOP? Seseorang yang tidak mengerti OOP masih dapat memprogram di Jawa. Juga, jangan bingung kesulitan untuk memahami dengan tidak mau mengikuti metode tertentu atau tidak setuju dengan itu.

6
JeffO

Anda harus membaca Objects Never? Well, Hardly Ever. (diperlukan keanggotaan ACM) oleh Mordechai Ben-Ari yang menyarankan bahwa OOP sangat sulit, karena itu bukan paradigma) itu sebenarnya wajar untuk memodelkan apa pun. (Meskipun saya memiliki keraguan tentang artikel tersebut, karena tidak jelas kriteria apa yang menurutnya perlu dipenuhi oleh sebuah program untuk mengatakan bahwa itu ditulis pada paradigma OOP sebagai lawan dari paradigma prosedural menggunakan bahasa OO.)

5
Ken Bloom

Pemrograman Berorientasi Objek itu sendiri tidak sulit.

Bagian yang sulit adalah melakukannya dengan baik. Di mana harus meletakkan potongan di antara kode sehingga Anda dapat dengan mudah memindahkan sesuatu ke objek basis umum, dan memperpanjangnya nanti? Cara membuat kode Anda dapat digunakan oleh orang lain (memperluas kelas, membungkus proxy, menimpa metode) tanpa melompat melalui lingkaran untuk melakukannya.

Itu adalah bagian yang sulit, dan jika dilakukan dengan benar bisa sangat elegan, dan jika dilakukan dengan buruk bisa sangat kikuk. Pengalaman pribadi saya adalah bahwa itu memerlukan banyak latihan untuk berada dalam semua situasi di mana Anda akan BERHARAP bahwa Anda melakukannya secara berbeda, untuk melakukannya dengan cukup baik ini waktu.

5
user1249

Saya sudah melakukan pemrograman GW-Basic dan Turbo Pascal sedikit sebelum diperkenalkan ke OO, jadi awalnya itu MELAKUKAN lakukan kepala saya.

Tidak tahu apakah ini yang terjadi pada orang lain, tetapi bagi saya itu seperti ini: proses pemikiran saya tentang pemrograman murni prosedural. Seperti dalam: "ini dan itu terjadi, maka ini dan itu terjadi selanjutnya", dll. Saya tidak pernah menganggap variabel dan data lebih dari sekadar aktor sekilas dalam aliran program. Pemrograman adalah "aliran tindakan".

Saya kira apa yang tidak mudah dipahami (sebodoh yang terlihat bagi saya sekarang), adalah gagasan bahwa data/variabel sebenarnya benar-benar penting , dalam arti yang lebih dalam dari sekadar menjadi aktor sekilas dalam "aliran" program. Atau dengan kata lain: Saya terus berusaha memahaminya melalui apa yang terjadi , daripada melalui apa itu , yang merupakan kunci nyata untuk menggenggamnya.

4
Bobby Tables

Saya baru saja menonton video oleh Richard Feynman yang membahas bagaimana orang-orang mungkin benar-benar memiliki metodologi yang berbeda dalam pikiran mereka ketika berpikir - maksud saya sama sekali berbeda.

Ketika saya melakukan desain tingkat tinggi, saya kebetulan memvisualisasikan objek, saya bisa melihatnya, melihat antarmuka mereka dan melihat jalur apa yang perlu dilalui informasi.

Saya juga mengalami kesulitan mengingat detail dan menemukan OO sebagai alat bantu organisasi yang hebat - jauh lebih mudah untuk menemukan fungsionalitas daripada memindai melalui daftar subrutin yang terorganisir secara longgar.

Bagi saya OO adalah manfaat besar, tetapi jika Anda tidak memvisualisasikan dengan cara yang sama atau tidak melakukan arsitektur tingkat tinggi, itu mungkin tidak ada gunanya dan menjengkelkan.

4
Bill K

Saya tidak berpikir itu sulit untuk dipahami tetapi mungkin banyak programmer yang bertanya pada konsep ini, berasal dari bahasa prosedural.

Dari apa yang saya lihat/baca banyak orang (di forum setidaknya) mencari 'hasil' dari OOP. Jika Anda seorang programmer prosedural yang tidak kembali dan memodifikasi memperpanjang kode mereka mungkin sulit untuk memahami manfaatnya.

Juga, ada banyak _ OOP yang buruk di luar sana, jika orang membaca/melihat itu maka mudah untuk melihat mengapa mereka merasa kesulitan.

IMO Anda harus menunggu sampai 'klik' atau diajar oleh seseorang dengan pengetahuan nyata, saya tidak berpikir Anda bisa Rush.

3
DBlackborough

Saya pikir alasan OOP sulit bagi banyak orang adalah karena alat tidak benar-benar memfasilitasi itu.

Bahasa komputer saat ini adalah abstraksi dari apa yang terjadi di komputer.

OOP adalah cara abstrak untuk mewakili abstraksi.

Jadi kami menggunakan abstraksi untuk membangun abstraksi dengan abstraksi. Tambahkan ke ini bahwa apa yang kita abstraksi biasanya interaksi fisik/sosial yang sangat kompleks dan, yah, tidak heran.

3
ElGringoGrande

Saya sebenarnya memiliki sebuah blog bernama "Perjuangan dalam Pemrograman Berorientasi Objek," yang lahir dari beberapa perjuangan saya untuk mempelajarinya. Saya pikir itu sangat sulit bagi saya untuk mengerti karena saya menghabiskan begitu banyak waktu menggunakan pemrograman prosedural, dan saya memiliki waktu yang sulit mendapatkan kepala saya di sekitar gagasan bahwa suatu objek dapat diwakili oleh kumpulan atribut dan perilaku (saya terbiasa hanya kumpulan variabel dan metode).

Juga, ada banyak konsep yang membuat objek bahasa berorientasi - pewarisan, antarmuka, polimorfisme, komposisi, dll. Ada banyak yang harus dipelajari tentang teori itu sebelum Anda benar-benar dapat menulis kode secara efektif, dan dalam objek-berorientasi cara, sedangkan dengan pemrograman prosedural, itu hanya masalah memahami hal-hal seperti alokasi memori untuk variabel, dan panggilan titik masuk ke metode lain.

2
Tim Claason

Motivasi. Lebih sulit untuk mempelajari sesuatu ketika Anda tidak melihat mengapa, dan juga ketika Anda tidak dapat melihat apa yang Anda lakukan dan mencari tahu apakah Anda melakukannya dengan benar atau tidak.

Apa yang dibutuhkan adalah proyek kecil yang menggunakan OO untuk melakukan hal-hal yang berguna. Saya sarankan melihat-lihat buku tentang pola desain dan menghasilkan yang jelas berguna dan bekerja dengan baik dengan OO. (I menggunakan Strategi saat saya mencobanya. Sesuatu seperti Flyweight atau Singleton akan menjadi pilihan yang buruk, karena mereka cara menggunakan objek secara umum, tidak menggunakan objek untuk mencapai sesuatu.)

2
David Thornley