Apakah kita benar-benar membutuhkan bahasa OO untuk mengelola kompleksitas perangkat lunak?

209

Ini akan menjadi pertanyaan yang sangat non-teknis, lunak dan saya tidak yakin apakah ini platform yang tepat. Tapi saya seorang siswa CS pemula jadi saya harap kalian menoleransi itu.

Pada semester pertama kami diperkenalkan dengan konsep OOP seperti enkapsulasi, penyembunyian data, modularitas, pewarisan dan sebagainya melalui Java dan UML. (Java adalah bahasa pemrograman pertama saya)

Cara saya memahaminya, OOP adalah cara mengelola kompleksitas perangkat lunak. Tetapi prinsip-prinsipnya tidak baru atau unik, mereka dalam arti universal untuk semua bidang teknik.

Misalnya mobil adalah struktur yang sangat kompleks yang kerumitannya dikelola oleh hierarki komponen modular dan dikemas dengan perilaku dan antarmuka yang terdefinisi dengan baik.

Tapi saya tidak mengerti alasan di balik memperkenalkan paradigma pemrograman baru. Saya pikir semua prinsip yang digunakan untuk mengelola kompleksitas dapat diwujudkan dengan bahasa pemrograman prosedural. Sebagai contoh, untuk modularitas kita hanya dapat membagi program menjadi banyak program kecil yang melakukan tugas-tugas yang didefinisikan dengan baik yang kodenya terkandung dalam file terpisah. Program-program ini akan berinteraksi satu sama lain melalui input dan output yang terdefinisi dengan baik. File-file tersebut mungkin dilindungi (terenkripsi?) Untuk mencapai enkapsulasi. Untuk penggunaan ulang kode, kita dapat memanggil file-file itu kapan saja mereka dibutuhkan dalam program baru. Tidakkah ini menangkap semua OOP atau apakah saya kehilangan sesuatu yang sangat jelas?

Saya tidak meminta bukti bahwa OOP mengelola kompleksitas. Menurut pendapat saya itu memang benar. Tetapi saya pikir semua prinsip yang digunakan untuk mengelola kompleksitas seperti modularitas, enkapsulasi, penyembunyian data, dan sebagainya dapat dengan mudah diimplementasikan oleh bahasa prosedural. Jadi mengapa benar-benar OOP jika kita dapat mengelola kompleksitas tanpa itu?

pertukaran steakex
sumber
41
Anda kehilangan pemisahan antarmuka dan implementasi. Mampu menukar satu implementasi dengan yang lain saat runtime adalah fitur yang sangat penting. Pada dasarnya, ini dicapai dengan metode pengiriman dinamis bahasa OO dengan warisan. Bahasa prosedural juga dapat melakukan hal itu (baca: void pointer), tetapi tanpa jenis keamanan.
marstato
81
Untuk sebagian besar, gagasan bahasa dan desain Berorientasi Objek adalah tepatnya untuk membuat konsep universal dan intuitif semudah mungkin untuk diwakili dan diciptakan kembali dalam kode. Jika Anda memiliki skema atau serangkaian pedoman untuk bagaimana mencapai semua hal itu tanpa bahasa Berorientasi Objek, maka proposal Anda tentang cara melakukan sesuatu akan secara efektif menjadi metodologi Berorientasi Objek yang digunakan. Bahasa OO yang sebenarnya hanyalah cara untuk memformalkan dan menyederhanakannya.
Standback
14
@RobbieDee, apakah Anda benar-benar membaca pertanyaan saya? Ini adalah tentang mencoba memahami OO pada tingkat yang lebih mendasar dengan mempertanyakan cuaca kompleksitas perangkat lunak dapat dikelola tanpa OO. Saya tidak mencoba untuk melemahkan OO, tidak mencoba untuk menciptakan sesuatu yang baru, saya hanya mencoba untuk memahaminya dengan lebih baik dan jika pertanyaannya begitu 'jelas' mengapa ia menerima jawaban yang sangat baik dari Jorg?
steakexchange
12
Mengenkripsi file bukan enkapsulasi. Anda mungkin telah mengaburkan melihat konten kode dari pengembang lain, tetapi Anda belum tentu melindungi bagian dalam kode dari kode lain. Penulis asli dapat melakukan ini sebelum atau sesudah enkripsi jika ia dapat mengingat caranya.
JeffO
8
Anda tidak memerlukan apa pun di luar bahasa mesin - biarkan programmer menghafal opcode dan menulis yang dan nol sendiri. Tetapi memiliki semacam bahasa "simbolis" sangat berguna dalam hal mengurangi kesalahan dan meningkatkan produktivitas, dan, seperti yang diamati Dijkstra, bahasa yang memaksakan beberapa "struktur" (atau setidaknya membuat menjaga "struktur" lebih mudah) sangat membantu. Bahasa OO mungkin bukan teknologi yang ideal, mengingat tingkat kecanggihan bahasa saat ini, tetapi mereka cukup bagus untuk banyak aplikasi. Idenya adalah mengelola kompleksitas tanpa menghalangi Anda.
Daniel R Hicks

Jawaban:

177

Biarkan saya coba dengan jawaban teori yang sangat rendah :)

Apa yang sebenarnya Anda tanyakan adalah: Mengapa menyertakan dukungan untuk Object Orientation (OO) langsung dalam bahasa ketika bahasa prosedural dapat digunakan untuk merancang dan menulis kode OO?

Dan jawabannya adalah: Untuk memiliki standar bagaimana OO diekspresikan dalam kode sumber sehingga Anda tidak berakhir dengan 22 implementasi yang berbeda untuk abstraksi yang sama.

Sebagai contoh, katakanlah saya membuat MagicButtondan MagicSlideryang dapat digunakan dalam sistem antarmuka pengguna. Saya perlu cara untuk mengelompokkan metode yang dapat digunakan dengan MagicButton, metode yang hanya dapat digunakan dengan MagicSlider, dan metode yang dapat digunakan oleh keduanya. Objek-objek ini berbagi beberapa metode karena keduanya adalah objek Magic gui.

Saya dapat melakukan pengelompokan dengan memberi nama fungsi dengan cara khusus MagicSlider_DoSomething ..., dengan memasukkan metode dalam file tertentu yang dinamai dengan cara khusus MagicSliderMethods.XXX, atau saya dapat menemukan beberapa cara khusus lain untuk melakukan hal yang sama. Jika tidak ada cara standar dalam bahasa untuk melakukannya, saya akan melakukannya berbeda dari Anda, dan berbeda dari orang lain. Ini membuat kode berbagi jauh lebih sulit.

Ya, keterlambatan pengiriman - metode virtual dalam bahasa OO - dapat diimplementasikan dalam bahasa prosedural, tetapi ada banyak cara berbeda untuk mengimplementasikannya. Bergantung pada siapa yang menulis kode Anda akan berakhir dengan implementasi OO yang berbeda di dalam program yang sama.

Pikirkan tentang pengembang pemeliharaan yang buruk. Orang ini harus mengelola abstraksi objek yang berbeda dan cara yang berbeda untuk memanggil metode virtual tergantung pada siapa yang menulis kode asli.

Juga: Memiliki abstraksi dalam bahasa memungkinkan editor kode tingkat lanjut seperti Eclipse untuk melakukan banyak analisis statis pada kode. Misalnya Eclipse dapat menawarkan daftar semua metode yang dapat digunakan pada objek, serta implementasi otomatis dari "metode TODO" kosong. Eclispe tahu persis metode mana yang harus diterapkan oleh kelas Anda berdasarkan kelas mana yang Anda perluas dan antarmuka mana yang Anda terapkan. Ini hampir mustahil jika tidak ada standar bahasa untuk melakukan OO.

MTilsted
sumber
40
Contoh klasik: Lua. Ini bukan OO asli, tetapi dapat dibuat untuk, tetapi ini berarti ada sekitar 5 perpustakaan OO yang sama-sama terkenal yang tidak sepenuhnya dapat dioperasikan.
Kroltan
55
@steakexchange Anda terlalu fokus pada hal-hal absolut. Sangat sedikit yang memiliki "tujuan tunggal". Bahasa semua melakukan banyak hal yang berbeda untuk tingkat kualitas yang berbeda. Memilih bahasa berarti memilih serangkaian pertukaran yang membuatnya paling pas untuk tujuan yang Anda butuhkan.
Tim B
42
@nocomprende Standarisasi abstraksi hampir secara harfiah untuk bahasa pemrograman apa. Bahkan abstrak bahasa rakitan atas perbedaan melintasi sesuatu seperti sepuluh generasi perangkat keras selama satu setengah dekade.
David Moles
56
@DavidMoles Abstraksi terstandarisasi secara harfiah adalah bahasa pemrograman. Jangan sia-siakan kesempatan sempurna untuk menggunakan "secara harfiah" secara harfiah!
Clement Cherlin
12
Dimungkinkan untuk membuat standar ini. Ketika saya berada di uni kembali di pertengahan 90-an, saya melakukan cukup banyak pekerjaan di X-Windows (kebanyakan didasarkan pada Motif, bagi mereka yang mengingat hal-hal seperti itu). X-Windows memang memungkinkan Anda untuk menerapkan semua fitur orientasi objek dalam C biasa . Senam mental untuk melakukannya cukup besar, dan sangat bergantung pada orang-orang yang tidak melihat ke dalam kotak (di mana titik Kode Widget Schroedinger umumnya berakhir mati). Bahasa OO menyembunyikan hal ini dari coders, dengan cara yang sama seperti kompiler biasa untuk assembler, dan hidup lebih mudah.
Graham
211

Pada semester pertama kami diperkenalkan dengan konsep OOP seperti enkapsulasi, penyembunyian data, modularitas, pewarisan dan sebagainya melalui Java dan UML. (Java adalah bahasa pemrograman pertama saya)

Tidak satu pun dari mereka adalah konsep OOP. Mereka semua ada di luar OO, independen dari OO dan bahkan banyak ditemukan sebelum OO.

Jadi, jika Anda berpikir bahwa itulah yang dimaksud dengan OO, maka kesimpulan Anda benar: Anda dapat melakukan semua itu dalam bahasa prosedural, karena tidak ada hubungannya dengan OO .

Sebagai contoh, salah satu makalah mani tentang Modularitas adalah Pada Kriteria Untuk Digunakan dalam Sistem Penguraian menjadi Modul . Tidak disebutkan OO di sana. (Itu ditulis pada tahun 1972, saat itu OO masih merupakan ceruk yang tidak jelas, meskipun sudah berusia lebih dari satu dekade.)

Sementara Abstraksi Data penting dalam OO, itu lebih merupakan konsekuensi dari fitur utama OO (Messaging) daripada itu adalah fitur yang menentukan. Juga, sangat penting untuk diingat bahwa ada berbagai jenis abstraksi data. Dua jenis abstraksi data yang paling umum digunakan saat ini (jika kita mengabaikan "tidak abstraksi apa pun", yang mungkin masih digunakan lebih dari dua gabungan lainnya), adalah Abstrak Jenis dan Objek Data . Jadi, hanya dengan mengatakan "Menyembunyikan Informasi", "Enkapsulasi", dan "Abstraksi Data", Anda tidak mengatakan apa pun tentang OO, karena OO hanyalah satu bentuk Abstraksi Data, dan keduanya pada dasarnya berbeda secara mendasar:

  • Dengan Tipe Data Abstrak, mekanisme abstraksi adalah sistem tipe ; itu adalah tipe sistem yang menyembunyikan implementasi. (Tipe sistem tidak harus statis.) Dengan Objects, implementasinya tersembunyi di balik antarmuka prosedural , yang tidak memerlukan tipe. (Misalnya, itu dapat diimplementasikan dengan penutupan, seperti yang dilakukan dalam ECMAScript.)
  • Dengan Tipe Data Abstrak, instance dari ADT yang berbeda dienkapsulasi dari satu sama lain, tetapi contoh dari ADT yang sama dapat memeriksa dan mengakses perwakilan masing-masing dan implementasi pribadi. Objek selalu dienkapsulasi dari segalanya . Hanya objek itu sendiri yang dapat memeriksa perwakilannya sendiri dan mengakses implementasinya sendiri. Tidak ada objek lain , bahkan objek lain dengan tipe yang sama, instance lain dari kelas yang sama, objek lain yang memiliki prototipe yang sama, klon objek, atau apa pun yang bisa melakukan itu. Tidak ada .

Omong-omong, ini artinya di Java, kelas tidak berorientasi objek. Dua contoh dari kelas yang sama dapat mengakses representasi masing-masing dan implementasi pribadi. Oleh karena itu, instance dari kelas bukanlah objek, mereka sebenarnya adalah instance ADT. Java interface, bagaimanapun, jangan memberikan berorientasi objek abstraksi data. Jadi, dengan kata lain: hanya instance dari interface yang objek di Java, instance dari class tidak.

Pada dasarnya, untuk tipe, Anda hanya dapat menggunakan antarmuka. Ini berarti jenis parameter metode dan konstruktor, jenis kembali metode, jenis bidang contoh, bidang statis, dan bidang lokal, argumen ke instanceofoperator atau operator gips, dan argumen jenis untuk konstruktor tipe generik harus selalu berupa antarmuka. Kelas dapat digunakan hanya secara langsung setelah newoperator, di tempat lain.

Sebagai contoh, untuk modularitas kita hanya dapat membagi program menjadi banyak program kecil yang melakukan tugas-tugas yang didefinisikan dengan baik yang kodenya terkandung dalam file terpisah. Program-program ini akan berinteraksi satu sama lain melalui input dan output yang terdefinisi dengan baik. File-file tersebut mungkin dilindungi (terenkripsi?) Untuk mencapai enkapsulasi. Untuk penggunaan ulang kode, kita dapat memanggil file-file itu kapan saja mereka dibutuhkan dalam program baru. Tidakkah ini menangkap semua OOP atau apakah saya kehilangan sesuatu yang sangat jelas?

Apa yang Anda gambarkan adalah OO.

Itu memang cara yang baik untuk berpikir tentang OO. Faktanya, itulah yang ada di pikiran para penemu OO. (Alan Kay melangkah lebih jauh: dia membayangkan banyak komputer kecil mengirim pesan satu sama lain melalui jaringan.) Apa yang Anda sebut "program" biasanya disebut "objek" dan alih-alih "panggilan", kita biasanya mengatakan "mengirim pesan" ".

Orientasi Objek adalah semua tentang Pesan (alias pengiriman dinamis ). Istilah "Object Oriented" diciptakan oleh Dr. Alan Kay, desainer utama Smalltalk, dan ia mendefinisikannya seperti ini :

OOP bagi saya hanya berarti pengiriman pesan, penyimpanan lokal dan perlindungan dan menyembunyikan proses negara, dan sangat mengikat semua hal.

Mari kita jabarkan:

  • olahpesan ("pengiriman metode virtual", jika Anda tidak terbiasa dengan Smalltalk)
  • proses negara seharusnya
    • dipertahankan secara lokal
    • terlindung
    • tersembunyi
  • sangat mengikat semua hal

Dari segi implementasi, olahpesan adalah panggilan prosedur yang terikat akhir, dan jika panggilan prosedur terlambat, maka Anda tidak dapat mengetahui pada waktu desain apa yang akan Anda panggil, sehingga Anda tidak dapat membuat asumsi tentang representasi konkret negara. Jadi, sebenarnya ini tentang pesan, keterlambatan mengikat adalah implementasi dari pesan dan enkapsulasi adalah konsekuensi dari itu.

Dia kemudian mengklarifikasi bahwa " Gagasan besar adalah 'pesan' ", dan menyesal telah menyebutnya "berorientasi objek" daripada "berorientasi pesan", karena istilah "berorientasi objek" menempatkan fokus pada hal yang tidak penting (objek ) dan mengalihkan perhatian dari apa yang benar-benar penting (olahpesan):

Hanya pengingat lembut bahwa saya bersusah payah di OOPSLA terakhir untuk mencoba mengingatkan semua orang bahwa Smalltalk bukan hanya BUKAN sintaks atau perpustakaan kelas, bahkan bukan tentang kelas. Saya minta maaf karena saya telah lama menciptakan istilah "objek" untuk topik ini karena itu membuat banyak orang untuk fokus pada ide yang lebih rendah.

Gagasan besarnya adalah "pesan" - itulah inti dari Smalltalk / Squeak (dan itu adalah sesuatu yang tidak pernah sepenuhnya selesai dalam fase Xerox PARC kami). Orang Jepang memiliki kata kecil - ma - untuk "apa yang ada di antara" - mungkin padanan bahasa Inggris terdekat adalah "pengantara". Kunci dalam membuat sistem yang hebat dan dapat ditumbuhkan jauh lebih banyak untuk merancang bagaimana modul-modulnya berkomunikasi daripada apa sifat dan perilaku internal mereka. Pikirkan internet - untuk hidup, itu (a) harus memungkinkan berbagai jenis ide dan realisasi yang melampaui standar tunggal dan (b) untuk memungkinkan berbagai tingkat interoperabilitas yang aman antara ide-ide ini.

(Tentu saja, hari ini, kebanyakan orang bahkan tidak fokus pada objek tetapi pada kelas, yang bahkan lebih salah.)

Pesan adalah hal mendasar bagi OO, baik sebagai metafora maupun sebagai mekanisme.

Jika Anda mengirim pesan kepada seseorang, Anda tidak tahu apa yang mereka lakukan dengannya. Satu- satunya hal yang dapat Anda amati, adalah respons mereka. Anda tidak tahu apakah mereka memproses pesan itu sendiri (yaitu jika objek memiliki metode), jika mereka meneruskan pesan tersebut ke orang lain (delegasi / proxy), jika mereka memahaminya. Itulah enkapsulasi tentang semua, itulah tujuan dari OO. Anda bahkan tidak dapat membedakan proksi dari yang asli, asalkan merespons bagaimana Anda mengharapkannya.

Istilah yang lebih "modern" untuk "pengiriman pesan" adalah "metode pengiriman dinamis" atau "panggilan metode virtual", tetapi itu kehilangan metafora dan berfokus pada mekanisme.

Jadi, ada dua cara untuk melihat definisi Alan Kay: jika Anda melihatnya berdiri sendiri, Anda mungkin mengamati bahwa pesan pada dasarnya adalah panggilan prosedur yang terikat akhir dan ikatan yang mengikat menyiratkan enkapsulasi, sehingga kita dapat menyimpulkan bahwa # 1 dan # 2 sebenarnya redundan, dan OO adalah tentang pengikatan akhir.

Namun, ia kemudian mengklarifikasi bahwa hal yang penting adalah olahpesan, sehingga kita dapat melihatnya dari sudut yang berbeda: olahpesan terlambat. Sekarang, jika olahpesan adalah satu - satunya hal yang mungkin, maka # 3 akan sepele benar: jika hanya ada satu hal, dan hal itu adalah keterlambatan, maka semua hal terikat terlambat. Dan sekali lagi, enkapsulasi mengikuti dari olahpesan.

Poin-poin serupa juga dibuat dalam On Understanding Data Abstraction, Revisited oleh William R. Cook dan juga Proposalnya untuk Definisi Modern tentang "Objek" dan "Berorientasi Objek" :

Pengiriman operasi yang dinamis adalah karakteristik penting dari objek. Ini berarti bahwa operasi yang akan dipanggil adalah properti dinamis dari objek itu sendiri. Operasi tidak dapat diidentifikasi secara statis, dan secara umum tidak ada cara untuk [tahu] operasi apa yang akan dijalankan sebagai tanggapan terhadap permintaan yang diberikan, kecuali dengan menjalankannya. Ini persis sama dengan fungsi kelas satu, yang selalu dikirim secara dinamis.

Di Smalltalk-72, bahkan tidak ada benda! Ada hanya aliran pesan yang mendapat diurai, ditulis ulang dan dialihkan. Pertama datang metode (cara standar untuk mengurai dan mengubah rute aliran pesan), kemudian datang objek (pengelompokan metode yang berbagi beberapa keadaan pribadi). Warisan datang jauh kemudian, dan kelas hanya diperkenalkan sebagai cara untuk mendukung warisan. Andaikata kelompok riset Kay sudah tahu tentang prototipe, mereka mungkin tidak akan pernah memperkenalkan kelas sejak awal.

Benjamin Pierce dalam Jenis dan Bahasa Pemrograman berargumen bahwa fitur penentu Orientasi Objek adalah Open Recursion .

Jadi: menurut Alan Kay, OO adalah tentang pesan. Menurut William Cook, OO adalah tentang pengiriman metode dinamis (yang benar-benar hal yang sama). Menurut Benjamin Pierce, OO adalah tentang Open Recursion, yang pada dasarnya berarti bahwa referensi-diri diselesaikan secara dinamis (atau setidaknya itu cara untuk memikirkannya), atau, dengan kata lain, pengiriman pesan.

Seperti yang Anda lihat, orang yang menciptakan istilah "OO" memiliki pandangan yang agak metafisik pada objek, Cook memiliki pandangan yang agak pragmatis, dan Pierce memiliki pandangan matematika yang sangat ketat. Tetapi yang penting adalah: filsuf, pragmatis, dan ahli teori semuanya setuju! Pesan adalah satu pilar OO. Titik.

Perhatikan bahwa tidak disebutkan pewarisan di sini! Warisan tidak penting untuk OO. Secara umum, sebagian besar bahasa OO memiliki beberapa cara implementasi digunakan kembali tetapi itu tidak harus menjadi warisan. Bisa juga berupa beberapa bentuk delegasi, misalnya. Bahkan, The Treaty of Orlando membahas delegasi sebagai alternatif pewarisan dan bagaimana berbagai bentuk pendelegasian dan pewarisan mengarah pada titik desain yang berbeda dalam ruang desain bahasa yang berorientasi objek. (Perhatikan bahwa sebenarnya bahkan dalam bahasa yang mendukung warisan, seperti Java, orang sebenarnya diajarkan untuk menghindarinya, sekali lagi menunjukkan bahwa itu tidak perlu untuk OO.)

Jörg W Mittag
sumber
16
+100 - Kami secara inheren menyalahkan hal-hal karena mereka digunakan secara tidak patut.
JeffO
55
Maaf, tapi ini sangat salah. Alan Kay mungkin muncul dengan istilah itu, tetapi prinsip-prinsip itu ada sebelum Smalltalk. Pemrograman berorientasi objek berasal dari Simula, dan gaya OO-nya tidak ada hubungannya dengan "pesan". Hampir semua bahasa OO yang telah berhasil menjalankan prinsip-prinsip dasar yang ditetapkan dalam Simula - yang sama seperti yang kita lihat di Jawa - dan OO gaya Smalltalk telah gagal di "pasar ide" setiap kali diperkenalkan kembali, karena itu sama sekali tidak bekerja dengan baik. Nama itu satu - satunya hal yang benar-benar bermakna yang disumbangkan Kay.
Mason Wheeler
23
@steakexchange No. "Esensi OO," hal yang membuatnya benar-benar berbeda, adalah objek dengan metode virtual. Ada alasan mengapa tidak ada yang menggunakan Smalltalk: sistem message-passing bekerja sangat buruk pada skala individu-komputer. Setiap kali beberapa perancang bahasa yang naif tetapi bermaksud naif mencoba menerapkan kembali prinsip Smalltalk, akhirnya gagal. (Contoh terbaru adalah Objective-C, yang tidak akan pernah digunakan siapa pun jika Steve Jobs tidak mendorongnya ke seluruh tenggorokan komunitas iOS. Tidak pernah ditemukan traksi di luar ekosistem Apple, dan ada alasan untuk itu. )
Mason Wheeler
28
@MasonWheeler Bisakah Anda menguraikan komentar Anda dalam jawaban karena Anda memiliki pandangan yang berbeda dengan apa yang Jorg katakan?
steakexchange
20
Perlu juga dicatat bahwa konsep bahasa Berorientasi Objek banyak berkembang. Konsep-konsep leluhur itu mungkin tidak benar saat ini dengan banyak bahasa yang mengabaikan model lama dan merangkul multi-paradigma. Lihat C #, misalnya - bahwa bahasa mencampurkan hampir semua yang ada di bawah matahari sekaligus dan, sementara sebagian besar disebut sebagai bahasa OO, itu sebenarnya campuran dari berbagai paradigma. Itu memungkinkannya menjadi alat yang sangat ekspresif bagi pengembang di sekitarnya. Juga, OO Berbasis Kelas adalah salah satu dari banyak rasa yang sama-sama valid dari pemrograman OO.
T. Sar
66

Tetapi saya pikir semua prinsip yang digunakan untuk mengelola kompleksitas seperti modularitas, enkapsulasi, penyembunyian data, dan sebagainya dapat dengan mudah diimplementasikan oleh bahasa prosedural.

Ketika Anda mengatakan, "sangat mudah" Anda membuat pernyataan yang sangat berani. Cara saya membacanya adalah: "Saya tidak melihat kesulitannya, jadi pasti tidak terlalu besar." Ketika diutarakan seperti itu, menjadi jelas bahwa Anda tidak bertanya "mengapa kita membutuhkan OO", Anda bertanya "mengapa bukan kesulitan yang ditemui paradigma pemrograman lain yang mengarah pada penemuan OO yang segera terlihat oleh saya? "

Jawaban untuk pertanyaan itu adalah bahwa banyak dari kesulitan ini tidak ada dalam jenis program yang sedang Anda kerjakan. Anda tidak diminta untuk memperbarui kode spageti berusia 40 tahun. Anda tidak berusaha menulis pengelola tampilan baru untuk sistem operasi. Anda tidak men-debug aplikasi multithreaded terdistribusi.

Untuk banyak jenis program mainan yang kami para siswa CS ditugaskan untuk menulis, kami dapat juga menulisnya dalam BASIC atau perakitan sebagai Java atau Python. Itu karena kompleksitas tugas yang melekat sangat rendah, hanya ada satu pengembang, tidak ada masalah interoperabilitas warisan, kinerja tidak masalah, dan kode kemungkinan hanya akan pernah berjalan beberapa kali pada satu mesin.

Bayangkan mengambil sopir siswa dan meminta mereka untuk bergabung ke jalan yang sibuk di jam sibuk, pada transmisi manual tanpa sinkronisasi, menuju ke atas bukit yang curam. Bencana. Mengapa? Mereka tidak dapat mengelola tingkat kerumitan yang diperlukan untuk secara bersamaan mengikuti semua aturan yang diperlukan oleh tugas tersebut.

Sekarang bayangkan siswa yang sama, kendaraan yang sama, mengemudi dengan kecepatan berjalan di tempat parkir kosong. Mereka baik-baik saja, karena tingkat keterampilan mereka memadai untuk tugas itu. Tidak ada tekanan, risiko kecil, dan mereka dapat mengambil masing-masing tugas mulai, mencengkeram, menggeser, mempercepat, menyetir satu per satu.

Siswa itu mungkin bertanya mengapa kita memiliki transmisi otomatis, jika seorang pengemudi yang terampil dapat melakukan semua hal ini secara bersamaan? Jawabannya adalah bahwa pengemudi yang cukup terampil tidak, dalam kondisi optimal, perlu otomatis. Tapi kami tidak semua pengemudi profesional dalam kondisi puncak, dan kami biasanya menginginkan kenyamanan memiliki desainer mobil yang mengurus semua kerumitan itu bagi kami.

Pemrogram yang terampil dan cukup disiplin memang dapat membuat sistem kompleksitas-tinggi yang berfungsi dalam C, atau assembly. Tapi kita tidak semua Linus Torvalds. Kita juga tidak harus menciptakan perangkat lunak yang bermanfaat.

Saya pribadi tidak tertarik harus menemukan kembali semua fitur bahasa modern sebelum saya bahkan dapat mengatasi masalah yang ada. Jika saya dapat memanfaatkan bahasa yang menyertakan solusi untuk masalah yang sudah diselesaikan, mengapa saya tidak?

Jadi saya akan membalikkan pertanyaan Anda, dan bertanya kepada Anda, jika bahasa menyediakan fitur nyaman seperti enkapsulasi, dan polimorfisme, mengapa kita tidak menggunakannya?

Clement Cherlin
sumber
13
Jadi pada dasarnya adalah mungkin untuk melakukan OO dengan bahasa prosedural tapi itu melakukan hal-hal secara manual saat menggunakan bahasa OO standar yang otomatis dan disederhanakan.
steakexchange
6
@steakexchange Cukup banyak persis seperti itu.
Tim B
3
@steakexchange contoh sejarah yang baik dari ini adalah model objek untuk X Windows kembali pada hari itu. Itu ditulis dalam C tetapi didasarkan pada sistem berorientasi objek. Jadi, Anda harus mengikuti konvensi tertentu untuk berinteraksi dengannya sehingga kelas Anda akan bermain bagus dengan yang lainnya.
Ukko
7
@nocomprende Tentu saja. Tetapi seseorang mungkin membuat komputer seseorang tidak bisa di-boot dengan melakukan raw disk write daripada mengandalkan filesystem, dan akan benar-benar sulit untuk men-debug masalah dalam sistem objek ad-hoc yang dibangun oleh seorang pemula. Enkapsulasi, ketika dilakukan dengan benar, membuat kita dari campur tangan dengan sengaja atau tidak sengaja dengan hal-hal yang seharusnya tidak kita lakukan.
Clement Cherlin
3
Sangat menarik bagi saya bahwa contoh yang Anda berikan dari aplikasi yang akan mendapat manfaat dari OO sering tidak ditulis dalam bahasa OO. Spaghetti berusia 40 tahun kemungkinan ditulis dalam C, COBOL, FORTRAN atau REXX. Manajer tampilan kemungkinan ditulis dalam C (walaupun dengan konvensi OO-ish), dan banyak sistem multithreaded yang sukses ditulis dalam Erlang, Go atau C.
James_pic
22

Apa yang Anda gambarkan bukan OOP, itu abstraksi. Abstraksi hadir dalam semua model desain modern, bahkan yang bukan OOP. Dan OOP adalah jenis abstraksi yang sangat spesifik.

Pertama, perlu dicatat bahwa tidak ada definisi tunggal OOP, jadi mungkin ada orang yang tidak setuju dengan apa yang saya karakterisasikan sebagai OOP.

Kedua, penting untuk diingat bahwa OOP terinspirasi oleh model desain tradisional, sehingga kesamaan dengan desain mobil bukan kebetulan.

Namun, inilah beberapa cara OOP lebih bernuansa daripada apa yang Anda katakan:

  • Enkapsulasi: ini bukan hanya tentang memiliki set antarmuka untuk modul (yaitu abstraksi), ini tentang melarang akses di luar antarmuka ini. Di Jawa, mengakses variabel pribadi adalah kesalahan kompilasi, sedangkan dalam desain mobil Anda, Anda dapat (dalam beberapa kasus) menggunakan hal-hal dengan cara yang berbeda dari antarmuka yang diinginkan.

  • Warisan: Ini benar-benar hal yang membuat OOP unik. Setelah Anda mendefinisikan antarmuka, Anda dapat membuat banyak hal untuk mengimplementasikan antarmuka itu, dan Anda dapat melakukan ini dengan cara heirarkis, mengubah bagian spesifik dari implementasinya, sambil mewarisi semua bagian sebelumnya, secara besar-besaran mengurangi duplikasi kode.

    Jika Anda berpikir dalam hal komponen mobil yang dienkapsulasi, sebenarnya tidak ada yang setara dengan ini. Tidak ada cara bagi saya untuk membuat roda gigi dengan mengambil roda gigi yang berbeda dan mengubah bagian tertentu dari implementasinya. (Setidaknya saya tidak berpikir begitu, saya tidak tahu banyak tentang mobil).

  • Polimorfisme : Setelah Anda mendefinisikan antarmuka, apa pun yang menggunakan antarmuka itu tidak dapat dibedakan, dari sudut pandang operasi apa yang tersedia, dan Anda tidak perlu tahu implementasi apa yang digunakan untuk menggunakan antarmuka. Di sinilah subtyping dan Prinsip Pergantian Liskov menjadi penting.

  • Penggandengan : Aspek utama dari OOP adalah bahwa kami erat menghubungkan hal-hal dengan operasi yang sama, dan menyebarkan berbagai bentuk yang mereka dapat miliki. Data digabungkan dengan operasi pada data itu. Ini berarti sangat mudah untuk menambahkan bentuk data baru (implementasi baru), tetapi sangat sulit untuk menambahkan operasi baru ke antarmuka (karena Anda harus memperbarui setiap kelas yang mengimplementasikan antarmuka). Ini berbeda dengan Tipe Data Aljabar dalam bahasa fungsional, di mana sangat mudah untuk menambahkan operasi baru (Anda hanya menulis fungsi yang berhubungan dengan semua kasus), tetapi sulit untuk menambahkan varian baru (karena Anda perlu menambahkan yang baru huruf ke semua fungsi Anda).

Ya ampun
sumber
1
Jawaban yang bagus! Satu bagian yang saya tidak setuju: perbedaan Anda menggambar tentang enkapsulasi tidak valid. Enkapsulasi selalu berarti "melarang akses di luar antarmuka ini" - itu berlaku untuk pengaturan OOP dan non-OOP sama. Jadi bagian ini bukanlah sesuatu yang unik untuk OOP.
DW
@ WD Saya sudah mencoba mengklarifikasi ini, mengatakan bukan bahwa itu unik untuk OOP tetapi perbedaan antara enkapsulasi dan abstraksi. Terima kasih untuk umpan baliknya!
jmite
2
BAIK. Tetapi saya masih memiliki pandangan berbeda tentang apa yang ditulis di sini tentang hal itu. Anda menulis bahwa "inilah beberapa cara OOP lebih bernuansa daripada apa yang Anda katakan", tetapi enkapsulasi bukanlah cara OOP lebih bernuansa daripada apa yang ditulis dalam pertanyaan. Enkapsulasi adalah apa adanya, dalam paradigma apa pun. Dan di mana Anda menulis bahwa "Apa yang Anda gambarkan bukan OOP, itu abstraksi", saya pikir pertanyaan aslinya berusaha menggambarkan enkapsulasi (bukan hanya abstraksi). Saya kira saya hanya akan meninggalkan komentar ini sebagai perspektif yang berbeda. Saya pikir jawabannya sangat membantu!
DW
Warisan adalah fitur umum, tetapi beberapa bahasa OO penting tidak memilikinya.
Bradd Szonye
Jawaban yang bagus, tetapi IMO Anda melebih-lebihkan contoh mobil. Mesin untuk model tertentu memiliki antarmuka yang terdefinisi dengan baik (poros cam, braket pemasangan "wadah", dll.). Anda dapat mengganti karburator tua sederhana dengan yang disuntikkan bahan bakar, menambahkan turbo-charger, dll. Tanpa mempengaruhi transmisi. (Meskipun mesin diesel memang membutuhkan tangki bahan bakar IIRC yang dimodifikasi.) Sebaliknya, Anda dapat mengganti transmisi manual dengan otomatis dan AFAIK yang tidak mempengaruhi mesin sama sekali.
David
11

Apakah kita benar-benar membutuhkan bahasa OO untuk mengelola kompleksitas perangkat lunak?

Ini tergantung pada arti kata, "kebutuhan."

Jika "kebutuhan" berarti membutuhkan, tidak, kami tidak memerlukannya.

Jika "kebutuhan" berarti "memberikan manfaat yang kuat", maka saya akan berkata, "Ya," kami menginginkannya.

Gambar besar

Bahasa OO mengikat fungsionalitas ke data.

Anda dapat menghindari fungsi pengikatan dan penulisan ini yang menyampaikan nilai data.

Tapi kemudian Anda mungkin akan berakhir dengan rasi bintang data yang berjalan bersama, dan Anda akan mulai membagikan tupel, catatan, atau kamus data.

Dan sungguh, itu semua pemanggilan metode adalah: fungsi parsial pada set data terikat.

Fitur demi fitur

Fitur OOP:

  • Warisan memungkinkan untuk menggunakan kembali kode (mixins) dan konsep (Kelas Dasar Abstrak / antarmuka) - tetapi Anda bisa mendapatkannya dengan mendekor ulang fungsi dan variabel dalam sub-lingkup.
  • Enkapsulasi memungkinkan penyembunyian informasi sehingga kami dapat bekerja pada level abstraksi yang lebih tinggi - tetapi Anda dapat melakukan ini dengan file header, fungsi, dan modul.
  • Polimorfisme memungkinkan kita untuk menggunakan argumen dari tipe yang berbeda selama argumen tersebut mendukung antarmuka yang sama - tetapi kita dapat melakukannya dengan fungsi juga.

Namun, tidak satu pun dari hal-hal itu terjadi begitu mudah seperti dengan bahasa berorientasi objek dengan dukungan kelas satu dari fitur-fitur itu.

Referensi

Ada banyak kritik terhadap OOP .

Namun, penelitian tampaknya mengindikasikan bahwa kami mendapatkan produktivitas programmer yang lebih besar dari penggunaan kembali kode melalui OOP. Ini adalah temuan yang kontroversial, dan beberapa peneliti mengatakan mereka tidak dapat mereproduksi kenaikan produktivitas ini, mengingat kendala tertentu. (sumber)

Kesimpulan

Kami tidak "membutuhkan" OOP. Tetapi dalam beberapa kasus, pengguna menginginkan OOP.

Pemahaman saya adalah bahwa programmer dewasa bisa sangat produktif dalam gaya berorientasi objek. Dan ketika paket memiliki objek inti dengan antarmuka sederhana yang mudah dipahami, bahkan programmer baru bisa menjadi sangat produktif dengan cepat.

Aaron Hall
sumber
10

Saya akan mencoba untuk singkat.

Prinsip inti OO adalah kombinasi data dan perilaku dalam satu unit organisasi (objek).

Inilah yang memungkinkan kami untuk mengontrol kompleksitas dan itu adalah konsep yang cukup inovatif ketika muncul. Bandingkan dengan file di satu sisi (data murni), program yang membaca dan memproses file di sisi lain (logika murni) dan output (data murni lagi).

Hanya sekali Anda memiliki paket data dan logika bersama, memodelkan entitas dunia nyata, Anda dapat mulai bertukar pesan, membuat kelas anak, memisahkan pribadi dari data dan perilaku publik, menerapkan perilaku polimorfik, melakukan semua keajaiban khusus-OO ini.

Jadi, ya, OO adalah masalah besar. Dan tidak, itu bukan hanya sekelompok barang lama dengan nama mewah.

Membongkar semuanya, melihat elemen-elemennya dan kemudian berkata "oh, well, tidak ada apa pun di sini yang belum pernah saya lihat sebelumnya" tidak mengenali majelis yang memegang inovasi. Hasilnya lebih dari jumlah bagian-bagiannya.

Martin Maat
sumber
8

Tidak ada definisi "resmi" dari pemrograman berorientasi objek, dan orang-orang yang masuk akal tidak setuju pada apa yang sebenarnya mendefinisikan kualitas OO. Ada yang bilang pesan, ada yang bilang subtyping, ada yang bilang warisan, ada yang bilang bundling data dan perilaku. Itu tidak berarti istilah itu tidak ada artinya, hanya saja Anda tidak boleh terlalu terjebak dalam pertengkaran tentang apa sebenarnya OO itu.

Enkapsulasi dan modularitas adalah prinsip desain yang lebih mendasar, dan harus diterapkan dalam semua paradigma pemrograman. Para pendukung OO tidak mengklaim bahwa sifat-sifat ini hanya dapat dicapai dengan OO - hanya bahwa OO sangat cocok untuk mencapai ini. Tentu saja para pendukung paradigma lain seperti mengatakan pemrograman fungsional mengklaim hal yang sama untuk paradigma mereka. Dalam prakteknya banyak bahasa yang sukses adalah multi-paradigma dan OO, fungsional dll harus dilihat sebagai alat daripada "satu cara yang benar".

Saya pikir semua prinsip yang digunakan untuk mengelola kompleksitas dapat diwujudkan dengan bahasa pemrograman prosedural.

Benar, karena pada akhirnya Anda dapat melakukan apa saja dalam bahasa pemrograman apa pun. Mungkin lebih mudah di beberapa bahasa daripada di yang lain, karena semua bahasa memiliki kekuatan dan kelemahan yang berbeda.

JacquesB
sumber
7

Sesuatu yang belum dijawab oleh jawaban lain: nyatakan.

Anda berbicara tentang OO sebagai alat untuk mengelola kompleksitas . Apa kompleksitasnya? Itu istilah yang kabur. Kita semua memiliki perasaan gestalt tentang apa artinya, tetapi lebih sulit untuk menjabarkannya. Kita dapat mengukur kompleksitas siklomatik, yaitu jumlah jalur run-time melalui kode, tetapi saya tidak tahu itu yang sedang kita bicarakan ketika kita menggunakan OO untuk mengelola kompleksitas.

Apa yang saya pikir kita bicarakan adalah kompleksitas yang terkait dengan negara.

Ada dua ide utama di balik enkapsulasi . Salah satunya, menyembunyikan detail implementasi , cukup tertutup dalam jawaban lainnya. Tapi yang lain menyembunyikan kondisi run-time-nya . Kami tidak main-main dengan data internal objek; kami mengirim pesan (atau memanggil metode jika Anda lebih suka detail implementasi daripada konsep seperti yang ditunjukkan Jörg Mittag). Mengapa?

Orang-orang telah menyebutkan itu karena Anda tidak dapat mengubah struktur internal data Anda tanpa mengubah kode yang mengaksesnya, dan Anda ingin melakukannya di satu tempat (metode accessor) alih-alih 300 tempat.

Tapi itu juga karena membuat kode sulit untuk dipikirkan : kode prosedural (apakah dalam bahasa yang sifatnya prosedural atau hanya ditulis dengan gaya itu) menawarkan sedikit bantuan untuk memaksakan pembatasan pada mutasi negara. Apa pun bisa berubah kapan saja dari mana saja. Fungsi / metode panggilan mungkin memiliki aksi seram di kejauhan. Pengujian otomatis lebih sulit, karena keberhasilan tes ditentukan oleh nilai variabel non-lokal yang banyak diakses / diakses.

Dua paradigma pemrograman besar lainnya (OO dan fungsional) menawarkan solusi yang menarik, namun hampir sama sekali bertentangan dengan masalah kompleksitas terkait kondisi. Dalam pemrograman fungsional seseorang mencoba menghindarinya sepenuhnya: fungsi umumnya murni, operasi pada struktur data mengembalikan salinan daripada memperbarui yang asli di tempat, dll.

OO di sisi lain menawarkan alat untuk berurusan dengan mengelola negara (bukan alat untuk menghindarinya). Selain alat tingkat bahasa seperti pengubah akses (dilindungi / publik / pribadi), getter dan setter, dll. Ada juga sejumlah konvensi terkait seperti Hukum Demeter yang menyarankan agar tidak menjangkau objek melalui untuk mendapatkan data objek lainnya. .

Perhatikan bahwa Anda tidak perlu objek untuk benar-benar melakukan semua ini: Anda bisa memiliki penutupan yang memiliki data yang tidak dapat diakses dan mengembalikan struktur fungsi data untuk memanipulasinya. Tapi bukankah itu sebuah objek? Bukankah itu sesuai dengan konsepsi kita tentang apa objek itu, secara intuitif? Dan jika kita memiliki konsep ini, bukankah lebih baik mengulanginya dalam bahasa daripada (seperti jawaban lain katakan) mengandalkan ledakan kombinasi dari implementasi ad-hoc yang bersaing?

Jared Smith
sumber
5

Apakah kita benar-benar membutuhkan bahasa OO untuk mengelola kompleksitas perangkat lunak?

Tidak. Tetapi mereka dapat membantu dalam banyak situasi.

Saya telah menggunakan terutama satu bahasa OO selama beberapa dekade, tetapi sebagian besar kode saya sebenarnya benar-benar gaya prosedural pra-OO. Namun, untuk apa pun yang melibatkan GUI, saya menggunakan pustaka OO yang luas dari bahasa untuk metode dan objek bawaan, karena sangat menyederhanakan kode saya.

Misalnya, aplikasi Windows yang menggunakan API Windows tingkat rendah asli untuk menampilkan formulir, tombol, dan bidang edit memerlukan banyak kode, sedangkan sebaliknya menggunakan perpustakaan objek yang datang dengan Visual Basic atau C # atau Delphi membuat hal yang sama Program kecil dan sepele. Jadi, kode OO saya biasanya relatif kecil dan untuk GUI, sedangkan kode saya yang dipanggil objek-objek itu biasanya jauh lebih besar dan biasanya tidak peduli dengan menjadi OO (meskipun dapat bervariasi tergantung pada masalah yang saya coba selesaikan).

Saya telah melihat program OO yang terlalu rumit, bergantung pada aturan esoterik yang rumit tentang bagaimana objek diimplementasikan, dan bisa lebih sederhana jika ditulis tanpa konsep OO. Saya juga melihat yang sebaliknya: sistem kompleks yang menangis untuk diimplementasikan kembali dan disederhanakan dengan menggunakan objek.

Ketika Anda mendapatkan pengalaman, Anda akan menemukan situasi yang berbeda membutuhkan alat dan solusi yang berbeda, dan satu ukuran tidak cocok untuk semua.

joe snyder
sumber
3

Sebagai seseorang yang terlibat dalam proyek yang sangat besar seluruhnya ditulis dalam C, saya pasti dapat mengatakan bahwa jawabannya adalah "tidak" yang jelas.

Modularitas itu penting. Tapi modularitas dapat diimplementasikan dalam bahasa yang praktis. Sebagai contoh, C mendukung kompilasi modular, file header dan tipe struktur. Ini cukup untuk 99% kasus. Tentukan modul untuk setiap tipe data abstrak baru yang Anda butuhkan, dan tentukan fungsi untuk beroperasi pada tipe data. Terkadang, Anda menginginkan kinerja dan fungsi-fungsi itu ada di file header sebagai fungsi inline, di lain waktu Anda akan menggunakan fungsi standar. Itu semua tidak terlihat oleh pengguna cara mana yang dipilih.

Komposisi penopang struktur. Misalnya, Anda bisa memiliki tabel hash terkunci yang terdiri dari kunci mutex dan tabel hash biasa. Ini bukan pemrograman berorientasi objek; tidak ada subclass yang dilakukan. Komposisi adalah alat yang jauh lebih tua dari gagasan pemrograman berorientasi objek.

Untuk 1% kasus di mana kompilasi modularitas tidak cukup, dan Anda memerlukan modularitas runtime, ada hal yang disebut pointer fungsi. Mereka memungkinkan memiliki implementasi individual dari antarmuka yang terdefinisi dengan baik. Perhatikan bahwa ini bukan pemrograman berorientasi objek dalam bahasa yang tidak berorientasi objek. Ini mendefinisikan antarmuka dan kemudian mengimplementasikannya. Misalnya, subklas tidak digunakan di sini.

Pertimbangkan mungkin proyek open source paling kompleks yang ada. Yakni, kernel Linux. Itu sepenuhnya ditulis dalam bahasa C. Hal ini dilakukan terutama dengan menggunakan alat modularitas tingkat kompilasi standar termasuk komposisi, dan kemudian kadang-kadang setiap kali dibutuhkan modularitas runtime, fungsi pointer digunakan untuk mendefinisikan dan mengimplementasikan antarmuka.

Jika Anda mencoba menemukan contoh pemrograman berorientasi objek di kernel Linux, saya yakin menemukan contoh seperti itu sangat sulit, kecuali jika Anda memperluas pemrograman berorientasi objek untuk memasukkan tugas-tugas standar seperti "mendefinisikan antarmuka dan kemudian mengimplementasikannya".

Perhatikan bahwa bahkan bahasa pemrograman C mendukung pemrograman berorientasi objek jika Anda benar-benar membutuhkannya. Sebagai contoh, pertimbangkan toolkit antarmuka pengguna grafis GTK. Ini sebenarnya berorientasi objek, meskipun ditulis dalam bahasa yang tidak berorientasi objek. Jadi, ini menunjukkan bahwa gagasan bahwa Anda memerlukan "bahasa berorientasi objek" sangat cacat. Tidak ada yang bisa dilakukan oleh bahasa berorientasi objek yang tidak bisa dilakukan oleh jenis bahasa lain. Selain itu, jika Anda seorang programmer ahli, Anda tahu cara menulis kode berorientasi objek dalam bahasa apa pun dengan sangat mudah. Ini bukan beban untuk menggunakan C, misalnya.

Jadi, kesimpulannya adalah bahwa bahasa berorientasi objek mungkin hanya berguna untuk programmer pemula yang gagal memahami bagaimana konsep itu sebenarnya diimplementasikan. Namun, saya tidak ingin berada di dekat proyek di mana programmer adalah programmer pemula.

ahli hukum agama
sumber
1
"[...] kesimpulannya adalah bahwa bahasa berorientasi objek mungkin hanya berguna untuk programmer pemula yang gagal memahami bagaimana konsep itu sebenarnya diimplementasikan." Menarik. Bahasa apa yang Anda pikirkan? Apakah Anda memiliki contoh proyek sumber terbuka yang ditulis dalam bahasa-bahasa ini yang gagal atau tidak gagal?
Vincent Savard
3
Anda mendapatkan beberapa poin bagus, tetapi ide utama Anda cacat. Ya, adalah mungkin untuk menerapkan konsep OO seperti enkapsulasi, pengiriman virtual, pewarisan, dan bahkan pengumpulan sampah dalam bahasa seperti C. Hal ini juga dimungkinkan untuk dilakukan dalam perakitan. Itu tidak membuat pemrograman lebih mudah. Memprogram dan terutama mendesain dalam bahasa seperti C jelas lebih sulit daripada dalam bahasa OO. Dalam C Anda perlu memetakan konsep untuk implementasinya, dalam bahasa OO Anda tidak perlu melakukan langkah itu (setidaknya tidak untuk konsep OO).
Fishinear
1
"[function pointer] memungkinkan memiliki implementasi individual dari antarmuka yang terdefinisi dengan baik. Perhatikan bahwa ini bukan pemrograman berorientasi objek dalam bahasa yang tidak berorientasi objek. Ini mendefinisikan antarmuka dan kemudian mengimplementasikannya." Maaf, tapi itu benar-benar salah, karena ini adalah persis apa OOP adalah. "Misalnya, subclassing tidak digunakan di sini" Subclassing bukan fitur yang diperlukan dari OOP. Perhatikan, misalnya, bahwa JavaScript adalah bahasa berorientasi objek yang tidak memiliki fitur subkelas (atau, dalam hal ini, kelas sama sekali ... Hanya objek yang berisi referensi fungsi).
Jules
1
Untuk memperjelas komentar terakhir saya, poin saya adalah bahwa b faktor pembeda utama antara OOP (belum tentu ada bahasa OO spesifik) dan metode lain adalah bahwa dalam OOP kita mendefinisikan antarmuka yang beroperasi secara abstrak pada data tanpa perlu mengetahui format data dengan mengikat implementasi antarmuka ke data itu sendiri. Itulah OOP itu. Metode implementasi tidak relevan, apakah itu kelas gaya Java, objek JavaScript (secara efektif peta nama ke atribut, yang dapat berupa data atau kode) atau struktur yang berisi pointer fungsi dan kekosongan * untuk data.
Jules
1
"Jadi, kesimpulannya adalah bahwa bahasa berorientasi objek mungkin berguna hanya untuk programmer pemula yang gagal memahami bagaimana konsep itu benar-benar diterapkan." .... Dan ini, terus terang, benar-benar menghina. Saya cukup tahu bagaimana konsep-konsep ini diimplementasikan. Saya telah melakukan cukup banyak pekerjaan menggunakan kemudian menjadi mahir, bahkan. Saya bahkan telah mengimplementasikan penerjemah dan kompiler untuk bahasa OO di masa lalu. Tetapi karena saya lebih suka bekerja dalam bahasa tingkat tinggi yang memiliki objek kelas satu saya harus menjadi programmer pemula yang Anda lebih suka tidak bekerja dengan ?!
Jules
2

Alasan untuk memperkenalkan paradigma pemrograman, termasuk metode berorientasi objek, adalah untuk membuatnya lebih mudah untuk membuat program yang lebih canggih dan kuat. Dalam edisi Agustus 1981 dari Majalah Byte, Daniel Ingalls , salah satu pencipta kunci Smalltalk, mendefinisikan "berorientasi objek" sebagai melibatkan kemampuan berikut:

  • manajemen penyimpanan otomatis
  • kemampuan untuk bertukar pesan
  • metafora seragam yang berlaku untuk semua operasi bahasa
  • tidak ada komponen yang tergantung pada internal komponen lain (modularitas)
  • Program hanya mendefinisikan perilaku objek, bukan representasi mereka (polimorfisme)
  • setiap komponen hanya akan muncul di satu tempat (anjak piutang)
  • penggunaan mesin virtual yang merupakan perangkat keras independen
  • setiap komponen yang dapat diakses pengguna harus tersedia untuk observasi dan kontrol (prinsip reaktif)
  • seharusnya tidak ada pengontrol keseluruhan (tidak ada sistem operasi)

Ini adalah prinsip yang diidentifikasi Ingalls sebagai pertimbangan desain mengemudi untuk SmallTalk-80 yang dikembangkan oleh Xerox Parc Research. Dalam artikel majalah yang disebutkan di atas, Anda dapat membaca deskripsi terperinci dari masing-masing prinsip ini dan bagaimana mereka berkontribusi pada paradigma berorientasi objek menurut Ingalls.

Semua prinsip ini dapat diterapkan dengan menggunakan bahasa lengkap Turing, apakah itu prosedural, bahasa rakitan atau apa pun. Ini adalah prinsip desain, bukan spesifikasi bahasa. Bahasa berorientasi objek dimaksudkan untuk membuatnya lebih mudah untuk menggunakan prinsip-prinsip ini saat membuat perangkat lunak.

Misalnya, untuk mengambil prinsip pertama Ingall (manajemen penyimpanan otomatis), siapa pun dapat menulis sistem manajemen penyimpanan otomatis mereka sendiri dalam bahasa prosedural, tetapi akan banyak pekerjaan yang harus dilakukan. Saat menggunakan bahasa seperti SmallTalk atau Java yang memiliki manajemen penyimpanan otomatis bawaan, programmer tidak harus melakukan banyak hal seperti mengelola memori. Pengorbanannya adalah bahwa programmer kurang mendapat kendali atas cara memori digunakan. Jadi, ada manfaat dan kelemahannya. Gagasan paradigma desain seperti pemrograman berorientasi objek adalah bahwa manfaat dari paradigma akan lebih besar daripada kerugian untuk setidaknya beberapa programmer.

Tyler Durden
sumber
Saya pikir aturan yang sama akan berlaku dalam kasus Bahasa Khusus Domain. Kelebihan dan kekurangan yang sama ... Satu perbedaannya adalah bahwa DSL dapat dibuat cukup sederhana bagi pengguna akhir untuk bekerja dengannya, karena 'bahasa' sesuai dengan pemahaman mereka tentang ruang masalah, dan tidak ada lagi yang dimasukkan.
0

Salah satu cara mengelola kompleksitas perangkat lunak adalah dengan memisahkan kerangka kerja dari tindakan yang diinginkan sepenuhnya menggunakan Bahasa Spesifik Domain . Ini berarti bahwa level kode pemrograman berbeda dari level di mana hasil yang diinginkan dikonfigurasi - bahasa atau sistem yang sama sekali berbeda. Ketika ini dilakukan dengan benar, kode konvensional pada dasarnya menjadi perpustakaan, dan pengguna atau orang lain yang menciptakan hasil yang diinginkan menyambungkan hal-hal bersama-sama dengan bahasa scripting atau alat desain visual, seperti pembuat laporan.

Untuk bisa bekerja, ini membutuhkan gambar batas ketat di sekitar operasi apa yang mungkin dilakukan dan bagaimana mereka terhubung (bahasa skrip atau desain visual, seperti alat konstruksi formulir). Metadata adalah cara penting untuk mengabstraksi konfigurasi run-time dari detail pengkodean, sehingga memungkinkan suatu sistem untuk mendukung berbagai hasil yang diinginkan. Jika batas-batasnya ditetapkan dan dipegang (tidak menerima setiap permintaan untuk perpanjangan yang datang), Anda dapat memiliki sistem yang tahan lama dan kuat yang bekerja untuk orang-orang, tanpa mereka perlu menjadi programmer untuk mencapai apa yang mereka inginkan.

Martin Fowler telah menulis buku tentang ini, dan tekniknya hampir sama tuanya dengan pemrograman itu sendiri. Anda hampir bisa mengatakan bahwa semua bahasa pemrograman adalah Bahasa Khusus Domain, dan idenya endemik, diabaikan karena sangat jelas. Tetapi Anda masih bisa membuat skrip atau alat desain visual Anda sendiri untuk membuat hidup Anda lebih mudah. Terkadang generalisasi masalah membuatnya lebih mudah untuk dipecahkan!


sumber
0

Ini adalah pertanyaan yang sangat bagus dan saya merasa jawaban yang diberikan di sini belum melakukan keadilan, jadi saya akan melanjutkan dan menambahkan pemikiran saya.

Tujuannya adalah - Mengelola Kompleksitas Perangkat Lunak . Tujuannya bukan "menggunakan bahasa OO".

Tidak ada 'alasan' di balik memperkenalkan paradigma baru. Ini adalah sesuatu yang terjadi secara alami ketika pengkodean menjadi lebih matang. Lebih masuk akal untuk menulis kode di mana kita menambahkan pelatih di akhir kereta (kereta dimodelkan menggunakan daftar tertaut) daripada menambahkan simpul baru ke akhir daftar tertaut.


Coding dalam hal entitas dunia nyata adalah cara-cara yang jelas dan benar untuk kode ketika kita sedang coding tentang entitas dunia nyata.


Sebuah komputer dapat bekerja dengan menambahkan sebuah simpul ke akhir daftar yang terhubung semudah itu dapat bekerja dengan menambahkan pelatih tambahan di ujung kereta. Tetapi bagi manusia itu lebih mudah untuk bekerja dengan kereta dan pelatih daripada dengan daftar dan simpul yang terhubung meskipun ketika kita naik ke level yang lebih dalam, kita menemukan kereta dimodelkan melalui daftar yang terhubung.

Melindungi atau mengenkripsi file tidak dapat mencapai enkapsulasi. Kebalikan dari enkripsi adalah dekripsi. Kebalikan dari enkapsulasi adalah Dekapsulasi yang berarti Dekomposisi struktur dan kelas dalam bahasa pemrograman untuk mencapai kinerja yang lebih baik. Kinerja diperoleh dari mengurangi lalu lintas memori dan menghindari pemeriksaan aturan OOP.

Karenanya Anda dapat menulis kode yang terenkripsi dan juga dienkapsulasi dengan baik karena keduanya adalah konsep yang berbeda.

Enkapsulasi membantu dalam mengelola kompleksitas karena itu dekat dengan kenyataan.

Oleh karena itu, program dalam objek karena, lebih mudah bagi Anda untuk kode dan lebih cepat bagi Anda dan orang lain untuk mengerti.

nama tampilan
sumber
0

Satu hal yang perlu diingat adalah ini:
OOP bukan tentang fitur bahasa; ini tentang cara Anda menyusun kode Anda .

OOP adalah cara berpikir, dan merancang arsitektur kode Anda, dan dapat dilakukan dalam hampir semua bahasa. Ini terutama termasuk bahasa-bahasa tingkat rendah, non-OO, yang disebut assembler dan C. Anda dapat melakukan pemrograman berorientasi objek dengan sempurna di assembler, dan kernel Linux, yang ditulis dalam C, cukup berorientasi objek dalam banyak aspek .

Yang mengatakan, fitur OO dalam bahasa sangat mengurangi jumlah kode boilerplate yang perlu Anda tulis untuk mencapai hasil yang diinginkan . Di mana Anda perlu secara eksplisit mendefinisikan tabel fungsi virtual dan mengisinya dengan pointer fungsi yang sesuai di C, Anda tidak melakukan apa pun di Java, dan Anda selesai. Bahasa OO hanya menghapus semua yang memungkinkan cruft dari kode sumber, menyembunyikannya di belakang abstraksi tingkat bahasa yang bagus (seperti kelas, metode, anggota, kelas dasar, panggilan konstruktor / destruktor implisit, dll.).

Jadi, tidak, kita tidak perlu bahasa OO untuk melakukan OOP. Hanya saja, OOP jauh lebih mudah dilakukan dengan bahasa OO yang layak.

cmaster
sumber
-1

Pemrograman berorientasi objek lebih dari sekedar modul + enkapsulasi. Seperti yang Anda katakan, dimungkinkan untuk menggunakan enkapsulasi modul + dalam bahasa (prosedural) yang tidak berorientasi objek. OOP melibatkan lebih dari itu: melibatkan objek dan metode. Jadi, tidak, itu tidak menangkap OOP. Lihat, misalnya, https://en.wikipedia.org/wiki/Object-oriented_programming atau pengantar buku teks yang bagus untuk OOP.

DW
sumber
Terima kasih atas jawabannya. Bisakah Anda merekomendasikannya?
steakexchange
-2

Alasan terbesarnya adalah, ketika sebuah program menjadi lebih kompleks, Anda perlu membuat beberapa bagiannya tidak terlihat dari bagian lain, atau kompleksitas aplikasi dan jumlah fungsi akan membuat otak Anda menggiring bola keluar dari telinga Anda.

Mari kita bayangkan sistem 100 kelas, masing-masing dengan sekitar 20 operasi yang dapat dilakukan pada mereka; itu 2.000 fungsi. Namun, dari jumlah tersebut, mungkin hanya 500 yang merupakan operasi lengkap seperti 'Simpan' dan 'Hapus', sedangkan 1500 adalah fungsi internal yang melakukan sedikit pemeliharaan, atau memiliki peran utilitas. Mempertimbangkan;

// intentionally in a non-specific language!

setName(person, name) {
    nameParts = splitPersonName(name);
    person.firstName = nameParts[0];
    person.lastName = nameParts[1];
    person.modified = true;
}

splitPersonName(name) {
    var result = [];
    result.add(name.substring(0, name.indexOf(" ")));
    result.add(name.substring(name.indexOf(" ") + 1));
    return result;
}

Begitu SetNamejuga fungsi yang harus dilakukan orang terhadap seseorang, tetapi SplitPersonNamemerupakan fungsi utilitas yang digunakan oleh orang tersebut.

Pemrograman prosedural yang lurus tidak membuat perbedaan antara kedua operasi ini. Itu berarti 2.000 fungsional Anda semua bersaing untuk perhatian Anda. Namun, jika kita dapat menandai fungsi-fungsi ini sebagai 'tersedia untuk semua orang yang memiliki catatan orang' dan 'hanya digunakan sebagai fungsi utilitas di dalam catatan orang' maka perhatian kita sekarang adalah 500 'tersedia untuk fungsi semua orang', dan 15 'utilitas' fungsi untuk kelas yang sedang Anda edit.

Itu apa publicdan privatelakukan;

public class Person {
    public void setName(...) {...}
    private string[] splitPersonName(...) { ...}
}
pengguna62575
sumber
1
Saya tidak yakin apakah Anda memahami pertanyaan saya dengan benar. Saya sudah mengetahui enkapsulasi dan penyembunyian data sebagai cara untuk mengelola kompleksitas. Saya hanya berpikir bahwa ini dapat dengan mudah dilakukan dalam bahasa prosedural juga dengan membagi program menjadi modul yang melakukan tugas-tugas sederhana yang terdefinisi dengan baik yang pekerjaan dalamnya ditentukan dalam sumber-sumber yang dilindungi terpisah. Jadi mengapa OOP ketika kita bisa melakukan hal-hal itu dalam bahasa prosedural? Itu pertanyaan saya.
steakexchange
2
Saya kira jawaban saya adalah bahwa jika Anda ingin melakukan hal semacam ini, Anda harus menulis perkakas khusus dan konstruksi bahasa untuk melakukannya (misalnya, panggilan 'termasuk' khusus untuk menyertakan satu file yang mungkin tidak disertakan di tempat lain). Setelah Anda memulai jalur itu, Anda sebenarnya sudah mulai menerapkan bahasa berorientasi objek dengan cara Anda sendiri. Sebagai contoh, C ++ pada awalnya adalah preprocessor yang menghasilkan C polos , dan saya curiga setelah Anda menerapkan sistem Anda, itu terlihat seperti C ++ di atas C.
user62575
3
@steakexchange Perlu diketahui bahwa OOP dikembangkan di saat banyak bahasa prosedural tidak memiliki modul seperti itu. Beberapa bahkan tidak akan menyebut bahasa seperti itu prosedural. Memang, tidak ada yang mengatakan bahasa prosedural tidak boleh OO atau sebaliknya. Hati-hati dengan label - label dapat dengan mudah menyesatkan Anda. Jika bahasa prosedural Anda mendukung modul yang memiliki bidang dan prosedur publik dan pribadi, bagus untuk Anda :) Perbedaan utama antara "prosedural tradisional" dan "OOP" adalah bahwa pengiriman panggilan lebih fleksibel dalam OOP - memang, dalam OOP yang ketat, Anda tidak pernah tahu kode apa yang Anda panggil.
Luaan
2
@steakexchange Dalam bahasa ML-family, modul bekerja dengan baik, dan dalam kombinasi dengan lambdas, mereka memberi Anda semua kekuatan bahasa OO (setelah semua, fungsi adalah antarmuka dengan metode tunggal - bukankah itu hampir seperti yang direkomendasikan oleh "kode yang baik" orang-orang di OO?: P). Karena berbagai alasan, mereka masih kurang digunakan daripada bahasa yang lebih prosedural seperti C ++ atau Java, tetapi mereka memang memiliki daya tarik, dan banyak orang mencoba untuk mendidik orang tentang bagaimana mereka dapat menyederhanakan hidup mereka (dengan lebih atau kurang sukses).
Luaan
C secara efektif memiliki hal-hal ini. Ini memiliki modul (file .c) dengan antarmuka (file .h) dan dapat memiliki metode publik (extern) dan non-publik (extern) (fungsi). Anda bahkan dapat memiliki polimorfisme orang miskin dengan deretan pointer fungsi, saya tidak mengatakan OO mudah dalam C (atau mungkin, waras) tetapi enkapsulasi cukup mudah,
Nick Keighley