Berhentilah berdebat tentang pemrograman fungsional dan OOP

Pos berisi sejumlah olok-olok, Kementerian Kesehatan dengan meyakinkan meminta pembaca yang tidak siap untuk tidak membaca.

Artikel tentang topik "AF lebih baik" atau "OOP lebih baik" menyerupai debat tentang apa yang terbaik untuk makan siang, garpu, atau sendok. Secara tradisional, junes dimulai dengan sendok, tetapi seseorang yang sangat berwibawa pernah mengatakan kepada saya bahwa ia hanya makan daging dan menggunakan garpu, sehingga lahirlah mode baru - memakan garpu. Mereka makan bubur dan sup, dan bahkan berhasil meminum smoothies. Internet dipenuhi dengan artikel, seberapa baik kita, bahwa kita belajar makan smoothie dengan garpu dan mengatasi semua garu. Ini lucu dan sedih, di satu sisi, ini memberikan keunggulan kompetitif bagi orang-orang berpengalaman yang menunjukkan hasil super hanya mengabaikan sensasi ini, di sisi lain, mereka harus melatih kembali kolega dan karyawan, membersihkan sampah yang disebabkan oleh angin dari kepala mereka. Dalam artikel ini saya akan mencoba memberi tahu visi saya, yang tidak mengklaim sebagai kebenaran absolut, tetapi bekerja sangat baik dalam praktiknya

Seperti kebiasaan dalam sains, kita mulai dengan definisi. Definisi klasik OOP melibatkan mengikuti prinsip-prinsip pewarisan, enkapsulasi, dan polimorfisme. Tetapi jika kita tidak memiliki salah satu dari komponen ini, apakah itu akan menjadi OOP? Dan jika tidak, apa jadinya? Sementara bagian yang membosankan dari para penonton melayang-layang di atas tidak praktis dan tidak memberi kita pertanyaan, mari kita ingat apa yang terjadi sebelum PLO . Dan di depannya adalah pemrograman prosedural. Dan ide utama OOP pada saat itu adalah koneksi data dan fungsi untuk pemrosesan mereka . Idenya sederhana, tetapi cukup revolusioner, sulit untuk membayangkan berapa banyak, tetapi lebih lanjut tentang itu nanti.

Pemrograman fungsional, dalam interpretasi gratis, menganggap program sebagai rumus matematika . Formula diformalkan dengan baik dan dengan input yang sama mengembalikan output yang sama. Seluruh program terdiri dari rutinitas yang mengikuti prinsip yang sama. Bagaimana ini berbeda dari pemrograman prosedural yang sama? FP aktif menggunakan fungsi murni , idealnya seluruh program harus fungsi murni. Fungsi murni tidak memiliki efek samping , mereka dapat dengan mudah memoize, mudah diuji, dll ... Kita dapat mengatakan bahwa dalam fungsi murni ide utama dan keuntungan dari FP.

Dan sekarang dua pertanyaan:
- Bisakah kita menggunakan fungsi murni di OOP?
- Bisakah kita mengikat fungsi ke data di FP?
Jawaban keduanya adalah ya. Metode kelas statis dapat murni, bahkan metode instance dapat dianggap bersih jika mereka tidak membuat efek samping dan kami menganggap properti instance kelas sebagai parameter. Batas-batas definisi klasik meningkat dan beberapa mungkin tidak setuju, tetapi dalam praktiknya itu hanya berfungsi. Dan metode tersebut diformalkan dan diuji tidak lebih buruk dari fungsi klasik murni yang ditulis sesuai dengan semua kanon. Tentang metode pengikatan pada data sedikit lebih rumit, bahasa dan perpustakaan yang digunakan memaksakan pembatasan. Katakanlah dalam JavaScript ini dilakukan secara elemen, tidak yakin tentang Haskell dan Erlang. Sekarang hal yang paling menarik adalah apa yang diberikannya, dan mengapa OOP telah meningkatkan hype 20-30 tahun yang lalu. Jika Anda menulis sebuah program kecil - Anda dapat menulis sesuka Anda, kecuali untuk kecantikan Anda, itu tidak memengaruhi apa pun. Ketika Anda membuat program yang sangat besar, masalah kompleksitas muncul. Bukan dari kompleksitas komputasi, kami percaya bahwa di sini kami melakukan semuanya dengan baik, tetapi kompleksitas yang dirasakan. Katakanlah Anda memiliki 50.000 baris kode, dan semuanya bermanfaat. Bagaimana mengatur mereka agar tidak menjadi gila (atau tidak meninggalkan pekerjaan pada 11 malam)? Kami tidak dapat mengurangi jumlah operasi, tetapi kami dapat mengurangi jumlah koneksi di antara mereka (enkapsulasi membantu kami dalam hal ini). Kami menyembunyikan implementasi kompleks di belakang antarmuka yang sederhana dan terus bekerja hanya dengan antarmuka. Sebagai contoh, Internet adalah hal yang sangat rumit, tetapi kebanyakan pengembang memiliki pengetahuan yang cukup tentang protokol HTTP untuk melakukan pekerjaan mereka dan menyerahkan jaringan, fisik, dan tingkat lainnya ke administrator sistem . Semakin lemah konektivitas modul kami, semakin sedikit kompleksitas pada tahap integrasi satu sama lain. Semakin sedikit satu modul yang tahu tentang yang lain, semakin sedikit mereka terhubung. Metode pengikatan ke data di dalam modul membantu kita menyingkirkan pengetahuan ini dari para konsumen modul. Ini adalah keunggulan pragmatis utama OOP. Atas apa? Pendekatan di atas tanpa data dan metode yang mengikat. FP, seperti yang kami ketahui, tidak mengatakan apa-apa tentang ini. Anda bisa meneruskan kelas sebagai argumen ke fungsi murni, atau Anda bisa menggunakan fungsi murni sebagai metode kelas, itu tidak bertentangan satu sama lain, tetapi hanya menambahnya.

Dalam praktiknya, di mana terutama satu pendekatan bekerja, dan di mana yang lain terutama? Ketika saya menulis backend pada NodeJS, entah bagaimana ternyata dalam paradigma fungsional dengan sendirinya. Mengapa Karena permintaan ke server pada dasarnya adalah fungsi, dengan input dan output tetap. Pendekatan fungsional jatuh pada permintaan server dengan sangat alami dan kode lebih kompak dan fleksibel. Ketika saya membuat frontend untuk browser, OOP biasanya bekerja lebih baik, karena selain input dan output, kami juga memiliki aliran acara pengguna , serta acara program, seperti awal dan akhir animasi, permintaan server, dll ... Pendekatan fungsional bekerja jika hanya untuk menggambar halaman statis tanpa interaktivitas, ketika menggunakan FP di ujung depan, baik waktu interaktif atau pengembangan menderita (sesuai dengan pengukuran kami, setiap 3 kali). Mengapa

Setiap paradigma pemrograman didasarkan pada model realitas tertentu, dan model selalu merupakan penyederhanaan. Dalam FP, model ini memberlakukan lebih banyak pembatasan pada dunia, sehingga lebih mudah untuk diformalkan. Untuk alasan yang sama, ketika itu menjadi tidak relevan dengan kondisi masalah, itu mulai membutuhkan lebih banyak tongkat penyangga. Misalnya, FI ujung depan menyelesaikan masalah input pengguna dengan membuat berbagai acara (aksi, redux hi). Tetapi ini adalah abstraksi yang tidak relevan, yang, selain dampak kinerjanya, sangat meningkatkan waktu pengembangan. Dengan pendekatan ini, Anda dapat membuat daftar todo, tetapi pada proyek yang sangat besar Anda harus memecahkan batu bata dengan dahi Anda, dan kemudian menulis artikel kemenangan untuk yang sama malang. Sebagai perbandingan, ketika kami menulis terminal pertukaran (pada vanilla js, tentu saja) dengan kanvas, svg dan diperbarui beberapa kali per detik melalui websockets, dalam beberapa komponen yang sering diperbarui kami tidak menghapus divs, tetapi menggunakannya kembali, karena membuat ulang mereka relatif mahal operasi di browser (dan ini penting jika Anda memiliki aplikasi yang sangat besar ). Jika Anda memprogram di ujung depan, Anda bahkan tidak akan memiliki pemikiran seperti itu, karena Anda telah mencapai kesepakatan dengan kekekalan (omong-omong, ini adalah hal yang luar biasa untuk bekerja dengan multithreading, yang tidak terjadi di JS), sehingga setiap tindakan melewati setiap peredam dan sampah lainnya. Di sisi lain, di backend sering ternyata tanpa kelas sama sekali, karena di sana, Anda hanya dapat menghindari biaya pembuatannya, karena kondisi tugas sangat relevan dengan model FP. Tetapi, untuk sebagian besar, pengembang Java dan PHP tidak terburu-buru untuk mempelajari FP, vendor front-end berada di garis depan, yang benar-benar membutuhkannya. Sebagai latihan untuk pikiran - tentu saja menarik, hanya program yang diperoleh ... tetapi, dan orang lain menggunakannya. Terlepas dari kenyataan bahwa frontend adalah bagian IT yang relatif muda, dan tugas-tugasnya yang belum terpecahkan di sana selama beberapa generasi. Apa, tampaknya, bukan latihan untuk pikiran?

Source: https://habr.com/ru/post/id450300/


All Articles