OOP vs Pemrograman Fungsional vs Prosedural [ditutup]

237

Apa perbedaan antara paradigma pemrograman ini, dan apakah mereka lebih cocok untuk masalah tertentu atau apakah ada use-case yang lebih disukai dari yang lain?

Contoh arsitektur dihargai!

Ashutosh Singh-MVP SharePoint
sumber
Ini bukan jawaban lengkap, tapi saya menulis sedikit tentang bagaimana "fungsional" mempengaruhi / kontras gaya "OO" (dalam konteks F #) di sini: lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511. entri
Brian
Anda mungkin mempertimbangkan untuk membaca ini! Ada banyak contoh kapan harus menggunakan mana semut apa perbedaan utama, pro / kontra dll
Nikita Ignatov
1
Lihat juga: stackoverflow.com/questions/1530868
dreftymac
Paman Bob tweet tentang hal ini. Dan juga di sini .
jaco0646

Jawaban:

129

Semuanya baik dalam caranya sendiri - Mereka hanya pendekatan yang berbeda untuk masalah yang sama.

Dalam gaya prosedur murni, data cenderung sangat dipisahkan dari fungsi yang beroperasi di atasnya.

Dalam gaya berorientasi objek, data cenderung membawa kumpulan fungsi.

Dalam gaya fungsional, data dan fungsi cenderung memiliki lebih banyak kesamaan satu sama lain (seperti dalam Lisp dan Skema) sambil menawarkan lebih banyak fleksibilitas dalam hal bagaimana fungsi sebenarnya digunakan. Algoritma juga cenderung didefinisikan dalam hal rekursi dan komposisi daripada loop dan iterasi.

Tentu saja, bahasa itu sendiri hanya mempengaruhi gaya mana yang lebih disukai. Bahkan dalam bahasa fungsional murni seperti Haskell, Anda dapat menulis dalam gaya prosedural (meskipun sangat tidak dianjurkan), dan bahkan dalam bahasa prosedural seperti C, Anda dapat memprogram dalam gaya berorientasi objek (seperti di GTK + dan API EFL).

Agar jelas, "keunggulan" dari masing-masing paradigma hanyalah dalam pemodelan algoritma dan struktur data Anda. Misalnya, jika algoritme Anda melibatkan daftar dan hierarki, algoritme fungsional mungkin yang paling masuk akal. Atau, jika, misalnya, data Anda sangat terstruktur, mungkin lebih masuk akal untuk menjadikannya sebagai objek jika itu adalah paradigma asli bahasa Anda - atau, bisa dengan mudah ditulis sebagai abstraksi fungsional dari monad, yang adalah paradigma asli bahasa seperti Haskell atau ML.

Pilihan yang Anda gunakan hanyalah apa yang lebih masuk akal untuk proyek Anda dan abstraksi yang didukung bahasa Anda.

greyfade
sumber
5
Apa yang Anda katakan, sepertinya tidak mencerminkan apa yang Anda tulis. Anda mengatakan mereka tidak memiliki "pro dan kontra", dan kemudian mengatakan bagaimana mereka berbeda pendekatan. Mengapa seseorang memilih satu pendekatan daripada yang lain, berdasarkan situasi tertentu? kekuatan dan kelemahan, pro dan kontra, apa pun yang Anda sebut mereka memang ada! Saya tidak mengatakan bahwa secara inheren lebih baik, dan Anda juga tidak. Saya percaya itu yang sebenarnya ingin Anda katakan. kecuali Anda benar-benar percaya bahwa pendekatan apa pun yang dipilih tidak memiliki positif dan negatif, relatif terhadap pendekatan lain.
JM Becker
1
@ TechZilla: Saya setuju kata-kata saya jelek, tetapi yang saya maksudkan adalah bahwa sebenarnya tidak ada daftar fitur yang bisa Anda tunjuk dan katakan bahasa X lebih baik daripada Y tanpa kualifikasi bahwa bahasa X lebih cocok untuk menulis algoritma U dan bahasa Y mungkin lebih cocok untuk menulis algoritma V, sementara keduanya dapat dengan mudah diimplementasikan dalam kedua bahasa.
greyfade
2
Perbedaan antara prosedural dan fungsional tidak jelas bagi saya. Saya sedang belajar Skema / Rackett di College, tetapi saya benar-benar tidak dapat melihat perbedaan besar antara itu dan C atau PHP prosedural, dapatkah Anda memberikan beberapa contoh?
Leonel
7
@Leonel: Perbedaan terbesar yang akan dikutip kebanyakan orang adalah bahwa dalam bahasa prosedural, Anda mungkin menggunakan perulangan for, tetapi bahasa fungsional, tidak ada yang namanya - sebaliknya, Anda menggunakan panggilan rekursif ke berbagai fungsi untuk melakukan tugas yang sama. Bahasa fungsional juga membuat fungsi objek kelas satu - Anda dapat menyebarkannya seperti halnya angka - tetapi Anda tidak dapat melakukannya di C (dan dukungan PHP untuknya rusak).
greyfade
2
@tastro: Ketika satu paradigma lebih masuk akal daripada yang lain. Itu benar-benar semua. Terkadang lebih masuk akal untuk memodelkan kode Anda sebagai komposisi fungsi, dan terkadang lebih masuk akal untuk memodelkan data Anda sebagai objek. Ada banyak cara untuk mengekspresikan algoritma dan struktur data. OOP dan fungsional adalah dua hal itu.
greyfade
25

Saya pikir perpustakaan, alat, contoh, dan komunitas yang tersedia benar-benar mengalahkan paradigma akhir-akhir ini. Misalnya, ML (atau apa pun) mungkin merupakan bahasa pemrograman serbaguna untuk semua orang, tetapi jika Anda tidak bisa mendapatkan perpustakaan yang bagus untuk apa yang Anda lakukan, Anda akan gagal.

Misalnya, jika Anda membuat gim video, ada contoh kode dan SDK yang lebih baik di C ++, jadi Anda mungkin lebih baik dengan itu. Untuk aplikasi web kecil, ada beberapa kerangka kerja Python, PHP, dan Ruby yang hebat yang akan membuat Anda menjalankan dan menjalankannya dengan sangat cepat. Java adalah pilihan tepat untuk proyek yang lebih besar karena pengecekan waktu kompilasi dan perpustakaan dan platform perusahaan.

Dulu kasus bahwa perpustakaan standar untuk bahasa yang berbeda cukup kecil dan mudah direplikasi - C, C ++, Assembler, ML, LISP, dll. Datang dengan dasar-dasar, tetapi cenderung untuk keluar ketika datang ke standardisasi pada hal-hal seperti komunikasi jaringan, enkripsi, grafik, format file data (termasuk XML), bahkan struktur data dasar seperti pohon seimbang dan hashtable ditinggalkan!

Bahasa modern seperti Python, PHP, Ruby, dan Java kini hadir dengan perpustakaan standar yang jauh lebih baik dan memiliki banyak perpustakaan pihak ketiga yang baik yang dapat Anda gunakan dengan mudah, terima kasih banyak atas adopsi ruang nama mereka agar perpustakaan tidak saling bertabrakan, dan pengumpulan sampah untuk membakukan skema manajemen memori perpustakaan.

Dobes
sumber
5
Python, ruby, ... tidak memiliki perpustakaan "standar" seperti C atau LISP, karena mereka adalah bahasa implementasi tunggal. Python adalah apa yang dikatakan Guido, tidak ada standar. Setiap implementasi C atau LISP tertentu (atau apa pun) saat ini hadir dengan sejumlah besar perpustakaan di luar yang standar.
Dan Andreatta
8
Pertanyaannya adalah tentang perbedaan antara pemrograman berorientasi objek, fungsional, dan prosedural. Sementara bahasa yang disebutkan dalam jawaban-jawaban ini tentu saja cocok untuk salah satu dari pendekatan ini, jawabannya tidak menyebutkan konsep-konsep ini ... Terlepas dari apakah "perpustakaan yang tersedia [...] [mengalahkan] paradigma", itu tidak menjawab pertanyaan yang ada, dengan demikian mengesampingkan apa yang merupakan pertanyaan yang sepenuhnya valid.
rinogo
1
Kata-kata kasar yang berhubungan dengan ircmaxell
rinogo
20

Paradigma ini tidak harus saling eksklusif. Jika Anda melihat python, ia mendukung fungsi dan kelas, tetapi pada saat yang sama, semuanya adalah objek, termasuk fungsi. Anda dapat mencampur dan mencocokkan gaya fungsional / oop / prosedural dalam satu kode.

Yang saya maksud adalah, dalam bahasa fungsional (setidaknya dalam Haskell, satu-satunya yang saya pelajari) tidak ada pernyataan! fungsi hanya diperbolehkan satu ekspresi di dalamnya !! TAPI, fungsi adalah warga negara kelas satu, Anda dapat membagikannya sebagai parameter, bersama dengan banyak kemampuan lainnya. Mereka dapat melakukan hal-hal yang kuat dengan beberapa baris kode.

Sementara dalam bahasa prosedural seperti C, satu-satunya cara Anda bisa melewatkan fungsi adalah dengan menggunakan pointer fungsi, dan itu saja tidak memungkinkan banyak tugas yang kuat.

Dalam python, suatu fungsi adalah warga negara kelas satu, tetapi dapat berisi jumlah pernyataan yang berubah-ubah. Jadi Anda dapat memiliki fungsi yang berisi kode prosedural, tetapi Anda dapat menyebarkannya seperti bahasa fungsional.

Hal yang sama berlaku untuk OOP. Bahasa seperti Java tidak memungkinkan Anda untuk menulis prosedur / fungsi di luar kelas. Satu-satunya cara untuk melewatkan fungsi adalah dengan membungkusnya dalam objek yang mengimplementasikan fungsi itu, dan kemudian meneruskannya.

Dengan Python, Anda tidak memiliki batasan ini.

hasen j
sumber
Saya percaya Anda bermaksud "paradigma ini tidak harus saling eksklusif". 3 dari mereka adalah orthogonal dalam idealnya Anda bisa menggunakan satu, 2 atau 3 dari mereka dalam satu program (jika bahasa Anda memungkinkan).
Joe Pineda
Ya saya kira saling eksklusif adalah istilah yang lebih baik untuk itu! terima kasih
hasen
14

Untuk GUI saya akan mengatakan bahwa Paradigma Berorientasi Objek sangat cocok. Jendela adalah Objek, Kotak Teks adalah Objek, dan Tombol Oke juga. Di sisi lain, hal-hal seperti String Processing dapat dilakukan dengan overhead yang lebih sedikit dan karenanya lebih mudah dengan paradigma prosedural sederhana.

Saya rasa ini bukan masalah bahasa. Anda dapat menulis fungsional, prosedural atau berorientasi objek di hampir semua bahasa populer, meskipun mungkin ada beberapa upaya tambahan dalam beberapa bahasa.

panschk
sumber
17
Tergoda untuk downvote untuk mengabadikan kesalahpahaman bahwa "Object = GUI widget", tetapi saya akan menahan diri. OOP berfungsi dengan baik untuk mewakili konsep abstrak, seperti "UserAccount" atau "PendingSale", seperti untuk elemen antarmuka yang terlihat seperti "Window" dan "Button".
Dave Sherohman
5
Saya menulis bahwa sebuah jendela dapat menjadi objek. Bagaimana Anda menarik kesimpulan bahwa setiap Objek adalah jendela dari sana? Itu hanya sebuah contoh. Tentu saja OOP dapat digunakan juga untuk memodelkan entitas abstrak dan hubungannya. Ngomong-ngomong, terima kasih untuk tidak downvoting. Saya tidak punya banyak poin: D
panschk
6
-1. OOP tidak ada hubungannya dengan GUI. Idealnya, metode terbaik untuk mendesain guis adalah menggunakan file teks eksternal (mis. HTML). Sementara hal-hal seperti pemrosesan string sebenarnya jauh lebih baik dilakukan dengan objek. (pikirkan string dalam C) !!
hasen
1
Saya tidak tahu, mungkin saya hanya terbiasa pemrograman dengan objek untuk menyadarinya. Tetapi bagaimana Anda melakukan beberapa hal interaktif seperti mengubah nilai di TextBox X ketika nilai TextBox Y telah diubah tanpa menggunakan objek? Oke, Anda hanya bisa menggunakan vars global untuk segalanya ...
panschk
1
Pemrosesan string secara mengagumkan dilakukan dalam perl (100x lebih baik daripada di Java, C ++ atau C #) namun fungsionalitas string bahasa sama sekali TIDAK berorientasi objek. Penanganan string C mengerikan, tetapi kemudian C bukan satu-satunya bahasa prosedural (atau yang terbaik).
Joe Pineda
6

Untuk menjawab pertanyaan Anda, kami membutuhkan dua elemen:

  1. Memahami karakteristik berbagai gaya / pola arsitektur.
  2. Memahami karakteristik paradigma pemrograman yang berbeda.

Daftar gaya / pola arsitektur perangkat lunak ditampilkan pada artikel arsitektur perangkat lunak di Wikipeida. Dan Anda dapat meneliti mereka dengan mudah di web.

Singkatnya dan umum, Prosedural baik untuk model yang mengikuti prosedur, OOP baik untuk desain, dan Fungsional baik untuk pemrograman tingkat tinggi.

Saya pikir Anda harus mencoba membaca sejarah pada setiap paradigma dan melihat mengapa orang menciptakannya dan Anda dapat memahaminya dengan mudah.

Setelah memahami keduanya, Anda dapat menghubungkan item gaya / pola arsitektur ke paradigma pemrograman.

Gabriel Chung
sumber
2

Saya pikir mereka sering kali bukan "lawan", tetapi Anda bisa menggabungkannya. Saya juga berpikir bahwa seringkali, kata-kata yang Anda sebutkan hanyalah kata kunci. Ada beberapa orang yang benar-benar tahu apa arti "berorientasi objek", bahkan jika mereka adalah penginjil yang paling sengit.

Svante
sumber
1

Salah satu teman saya sedang menulis aplikasi grafis menggunakan NVIDIA CUDA . Aplikasi sangat cocok dengan paradigma OOP dan masalahnya dapat diuraikan menjadi modul dengan rapi. Namun, untuk menggunakan CUDA Anda harus menggunakan C, yang tidak mendukung warisan . Karena itu, Anda harus pintar.

a) Anda menyusun sistem pintar yang akan meniru warisan sampai batas tertentu. Itu bisa dilakukan!

i) Anda dapat menggunakan sistem kait , yang mengharapkan setiap anak C dari orangtua P memiliki fungsi override tertentu untuk F. Anda dapat membuat anak-anak mendaftarkan override mereka, yang akan disimpan dan dipanggil ketika diperlukan.

ii) Anda dapat menggunakan fitur penyelarasan memori struct untuk memasukkan anak-anak ke orang tua.

Ini bisa rapi tetapi tidak mudah untuk datang dengan solusi yang dapat diandalkan di masa depan. Anda akan menghabiskan banyak waktu merancang sistem dan tidak ada jaminan bahwa Anda tidak akan mengalami masalah setengah jalan melalui proyek. Menerapkan banyak warisan bahkan lebih sulit, jika hampir tidak mungkin.

b) Anda dapat menggunakan kebijakan penamaan yang konsisten dan menggunakan pendekatan divide and conquer untuk membuat program. Itu tidak akan memiliki warisan tetapi karena fungsi Anda kecil, mudah dipahami dan diformat secara konsisten, Anda tidak memerlukannya. Jumlah kode yang Anda butuhkan untuk menulis naik, sangat sulit untuk tetap fokus dan tidak menyerah pada solusi mudah (peretasan). Namun, cara pengkodean ninja ini adalah cara pengkodean C. Tetap seimbang antara kebebasan tingkat rendah dan penulisan kode yang baik. Cara yang baik untuk mencapai ini adalah dengan menulis prototipe menggunakan bahasa fungsional. Misalnya, Haskell sangat bagus untuk membuat prototipe algoritma.

Saya cenderung ke arah pendekatan b. Saya menulis solusi yang mungkin menggunakan pendekatan a, dan saya akan jujur, rasanya sangat tidak wajar menggunakan kode itu.

sneg
sumber
Copmpiler c ++ pertama tidak lebih dari pra-prosesor yang menghasilkan kode C. Dengan demikian, SEMUA fitur c ++ - termasuk multiple inheritance, dapat diimplementasikan menggunakan C. (meniru penanganan c ++ exception dalam C akan memerlukan beberapa jenis dukungan platform untuk pengecualian, tetapi implementasi c ++ memerlukan itu juga, jadi saya tidak berpikir itu membuat dasar ide tidak valid).
Chris Becke
2
@ Chris Becke jawaban Anda terlalu filosofis. Untuk satu, C memiliki beberapa standar (selama bertahun-tahun), hampir tidak ada satupun dari mereka yang sepenuhnya diadopsi oleh kompiler C apalagi c ++. Untuk mengatakan bahwa C ++ adalah superset dari C karena menggunakan sintaks C tidak berarti banyak karena Anda bahkan tidak dapat menulis kode untuk satu kompiler C yang dikompilasi dalam kompiler C lain tanpa usaha yang signifikan. Selain itu, ada fitur bahasa (sistem tipe, dukungan OOD) yang ditawarkan dalam bahasa lain yang tidak mungkin diimplementasikan dalam C tanpa menggunakan C untuk merancang bahasa baru (itulah mengapa ada 'bahasa baru')
Sprague
Kamu tahu. Saya tidak bisa melihat lagi relevansi komentar saya dengan postingan ini. : P
Chris Becke
Cuda telah mendukung C ++ untuk beberapa waktu sekarang.
Aryeh Leib Taurog