Funktsional va ob'ektga yo'naltirilgan dasturlash

Hey bolalar, maqolalar orasidagi kechikish uchun uzr. Men ushbu maqolada FP (Funktsional dasturlash) va OOP (Ob'ektga yo'naltirilgan dasturlash) o'rtasidagi farq haqida va har birini ulardan qachon foydalanish yaxshiroq ekanligi haqida gaplashaman.

Ko'pgina hollarda bitta uslub bilan nima qila olasiz, boshqasi bilan qilishingiz mumkin. Ammo, siz hal qilmoqchi bo'lgan muammoga qarab biri boshqasidan yaxshiroq bo'lishi mumkin. Uslublar siz qanday turdagi dasturlarni yozishingizni cheklamaydi, lekin ularni qanday yozishingiz kerak. Shuni aytib o'tish kerakki, hech kimning uslubi har doim ham yaxshi emas. Ikkalasini ham bilish yaxshidir, shuning uchun har qanday vaziyatda osonlikcha engishingiz mumkin. Shunday qilib, keling!

Ob'ektga yo'naltirilgan dasturlash

Bu eng taniqli paradigma. Nomidan ko'rinib turibdiki, uning markazida hamma narsa bor. Ob'ektlar ikkala ma'lumotni ham, shu ma'lumot asosida ishlaydigan funktsiyalarni ham o'z ichiga oladi. Eng yaxshisi, bu avtomobil analogini ishlatish edi.

Xulosa:
Bir yo'la mashina qurib bo'lmaydi. Siz uni kichikroq bo'laklarga bo'lishingiz kerak. U qadar kichkina emaski, bu eng mayda tafsilot. Ammo unchalik katta emaski, uni boshqarish juda katta bo'ladi. Asosan, siz murakkab ob'ektni kichikroq qismlarga ajratasiz.

Kapsülasyon:
Siz mashinani qismlarga bo'lgandan so'ng buzib tashlang. Ushbu qismlarning xususiyatlari haqida o'ylashingiz kerak. Masalan: radius va kenglik va shinadan foydalanish. Xuddi shu ma'noda, siz barcha qismlarni birlashtirib, o'zingizning mashinangizni qurasiz: ob'ekt tarkibi. Enkapsulatsiya - bu ma'lumotlarning guruhlanishi va ushbu ma'lumotlarda ishlash uchun funksionallik. Bu sizning kodingizni modulli qiladi.

Meros olish:
Shinalarning ko'p turlari mavjud. Qor shinalari, qishki shinalar, yozgi shinalar va boshqalar. Ularning barchasi o'xshash xususiyatlarga ega va ma'lum farqlar. Har bir shinalar uchun alohida sinf yozishni xohlamaysiz. Buning eng yaxshi tomoni shundaki, umumiy xususiyatlarga ega shablonni yaratish va keyin maxsus kodni o'z ichiga olgan maxsus sinflarni yaratish. Asosan, siz ota-ona tomonidan umumiy xususiyatlarga ega bo'lgan maxsus shinalarsiz: shinalar. Bu sizning kodingizni qayta ishlatishga imkon beradi.

Polimorfizm:
Bu oxirgi qism. Avtomobil haydashda hamma narsa qanday ishlashini bilishingiz shart emas. Avtomobil bilan shovqin qilish uchun siz gaz pedali, rul va vites almashtirishidan foydalanasiz. Sizda umumiy dastur bilan o'zaro ishlash uchun bitta yoki bir nechta interfeys mavjud va kodning ichki ishlashi haqida sizda hech qanday tasavvur yo'q. Bu sizning yaratuvchingizdan boshqa hech kim sizning kodingiz bilan aralashmasligi mumkinligiga ishonch hosil qiladi.

Funktsional dasturlash

Funktsional dasturlashning kaliti bu nomda: vazifalar. FP ob'ektlarga emas, balki o'zgarmas va kompozitsion funktsiyalarga tegishli. Keling, asosiy xususiyatlarni tezda ko'rib chiqaylik:

Vazifalar birinchi darajali. Ular atrofga o'tkazilishi, dinamik ravishda yaratilishi, ma'lumotlar tuzilmalarida saqlanishi va boshqa har qanday birinchi darajali ob'ekt kabi muomala qilinishi mumkin.

Sof funktsiyalardan foydalaning. Sof funktsiya - bu nojo'ya ta'sir ko'rsatmaydigan funktsiya. Sof funktsiyalar bilan dasturlash orqali siz modullikning ko'payishini sezasiz, bu kodni sinash, qayta ishlatish, parallellashtirish, umumlashtirish va asoslashni osonlashtiradi.

Vazifalar tuzilishi mumkin. Bu OOPdagi kapsülasyon kabi kinda. Kichikroq funktsiyalarni birlashtirish orqali siz kattaroq funktsiyalarni qurishingiz mumkin. Yodingizda bo'lsin, funktsiyalar birinchi darajali.

Ifodalar iboralarga qaraganda afzalroqdir. Ifodalar qiymatlarni beradi. Dastur oqimini boshqarishga yordam beradigan bayonotlar yo'q va mavjud.

Ma'lumotlar o'zgarmasdir. Ma'lumotlar tarkibini o'zgartirish o'rniga, samarali ravishda yangisi yaratiladi.

Ma'lumotlar o'zgartirilmaydi, o'zgartirilmaydi. Ma'lumotlar o'zgarmas ekan, uni o'zgartirish kerak. Shunday qilib, biron bir funktsiyaga ma'lumotlar strukturasini o'tkazganingizda, yangisi chiqadi va ichkarisi o'zgartirilmaydi.

Bu erda keng tarqalgan ip shundaki, yon ta'siri yo'q. Ammo bu nimani anglatadi? Qanday qilib yon ta'siri yo'qligini yozishingiz mumkin?

Hech qanday yon ta'siri kodning fuqaroligi yo'qligini anglatmaydi. Dasturning bajarilishida uning natijalarini hisoblashdan boshqa biron bir kuzatiladigan ta'siri yo'q. Bu mos yozuvlar shaffofligi g'oyasi bilan bog'liq. Agar barcha dasturlar uchun, dasturdagi ifoda etishning barcha holatlari, dasturning kuzatiladigan holatiga ta'sir qilmasdan, uni baholash natijasi bilan o'zgartirilishi mumkin bo'lsa, ifoda ravshan bo'ladi.

Masalan: 1 + 2 har doim teng bo'ladi 3. Shu ma'noda, u toza funksiya hisoblanadi, chunki berilgan kirishlar uchun hech qachon mahsulot o'zgarmaydi. Shunday qilib, 1 + 2 ni ko'rsangiz, uni 3 ga almashtirishingiz mumkin va dasturning umumiy bajarilishida hech qanday salbiy ta'sir ko'rmayapsiz.

Yo'naltiruvchi oshkoralik sizga almashtirish modelidan foydalanish imkoniyatini beradi. Siz algebradagi kabi iboralar haqida o'ylashingiz mumkin. O'zgaruvchilarni ularning qiymatlari bilan almashtirish orqali katta tenglamani echishingiz mumkin va uni eng oddiy shakliga kamaytirishingiz mumkin. Siz tengliklarni tenglashtirasiz.

O'ng tarafdan ko'rib turganingizdek, x mutlaqo shaffofdir. Teskari yoki boshqa usul bilan necha marta qo'ng'iroq qilishingizdan qat'iy nazar, chiqish qiymati har doim bir xil bo'ladi. Hech qanday yon ta'siri yo'q. Shunday qilib, x ni haqiqiy qiymati bilan almashtirishingiz va baribir bir xil natijani olishingiz mumkin. Bir vaqtning o'zida ishlashi kerak bo'lgan kodni yozayotganingizda bu juda yaxshi; muammolarga olib keladigan har qanday yon ta'siridan tashvishlanishingiz shart emas. Keling, ba'zi nojo'ya ta'sirlarni ko'rsatadigan kodni ko'rib chiqaylik.

Ko'rinib turibdiki, StringBuilder-ning teskari funktsiyasi toza, ammo qo'shimchalar funktsiyasi unday emas. Har safar qo'shimchaga qo'ng'iroq qilganingizda, chiqish qiymati o'zgaradi. Bu shunchaki shaffof emasligini anglatadi. Bir vaqtning o'zida dasturda bu halokatli bo'lishi mumkin. Xavotir olmang, yon ta'siri bo'lgan har qanday funktsiyani yadrodagi sof funktsiyaga va yon ta'siri bilan bir yoki bir nechta funktsiyaga bo'lish mumkin.

Yuqoridagi misoldagi kodni ko'rib chiqaylik. Biz pleerni eng yuqori ball to'playdigan deklaratsiyaWinner funktsiyasini yaratdik. Oddiy huquqmi? Endi biz ro'yxatda yoki boshqa ma'lumotlar strukturasida eng yuqori ball to'plagan pleerni topishni istasak nima bo'ladi? Agar kodning ba'zi qismlarini qayta ishlatmoqchi bo'lsak nima bo'ladi? Buni e'lon qiluvchining birinchi ta'rifi bilan aniq amalga oshirib bo'lmaydi.

Ammo, agar biz funktsiyani sof funktsiyaga va yon ta'siri bilan bittaga ajratsak. Biz buni aniq amalga oshira olamiz. Ko'rinib turibdiki, biz o'yinchilar ro'yxatini ko'rib chiqamiz va eng yuqori ball to'plagan o'yinchini juda oson topamiz. Bundan tashqari, bu bizning kodimizni yanada modullashtirdi va funktsiyalarni tuzishga imkon beradi.

Imperativ dasturlash

Bu shunchaki dastur holatini o'zgartiradigan ko'rsatmalar bilan dasturlash haqida. Biz hozirgacha OOP va FP bilan shug'ullanmoqdamiz. Kengaytma orqali siz FP va OOP asoslarini kerak bo'lganda aralashtirishingiz mumkin. Ular bir-biriga mutlaqo xos emas. Ular ma'lum muammolarni maqbul tarzda hal qilishning oddiy variantidir.

Masalan: Java klassik OOP tili. Ammo, Java 8-ga kelsak, u lambda funktsiyalarini qo'llab-quvvatlash orqali yanada funktsional bo'lib qoldi. Bu umuman funktsional emas, lekin u bora boshladi.

Ishlardan foydalaning

FP bilan esda tutish kerak bo'lgan narsa shundaki, ma'lum bir kirish uchun chiqish har doim bir xil bo'ladi va kirish har doim o'zgarmasdir. Hech qanday holat mavjud emas. Xavfsiz kodni yozish kerak bo'lganda, FP-ga o'ting.

OOP bilan holat o'zgarishi norma hisoblanadi. Muayyan kirish har doim ham bir xil chiqishga olib kelmaydi. Masalan: qidiruv tizimi haqida o'ylang. Google har doim bir xil qidiruv kaliti uchun bir xil natijalarni qaytarib bermaydi. Bu FP direktorlariga qarshi. Shunday qilib, bu holda OOP-dan foydalaning.

Bittasi boshqasidan yaxshiroq bo'lishi mumkin bo'lgan vaziyatlar ko'p. Xotiradan foydalanish OOPda yuqori bo'ladi, chunki hamma narsa ob'ektdir. FP har safar yangi element qo'shganda o'zgarmas ma'lumotlar strukturasining yangi nusxasini yaratishi kerak. Har birining o'z kamchiliklari bor.

Umid qilamanki, bu ikkala farqni juda yaxshi tavsifladi. Birozdan keyin FP uchun dizayn naqshlarini kiritaman. Shubhasiz, ular OOP dan farq qiladi. Shunday qilib, ularni bilish juda muhimdir. Shunday qilib, ehtiyot bo'ling!

FP va OOP meni qanday his qilmoqda.

Tahrirlash

Men aytib o'tmoqchi bo'lgan bir nechta narsalar bor:

Java umuman OOP tili emas. U ibtidoiy va statik a'zolarga ega, ularning ikkisi ham ob'ekt emas. Biroq, Scala butunlay OOP tilidir. Albatta, siz Scalada FP va OOP aralashmasi bo'lgan dasturlarni yozishingiz mumkin. Ammo, Scalada hamma narsa ob'ektdir, hatto funktsiyalar ham mavjud.

Xo'sh, nima uchun uni Java orqali tanlaysiz? Xo'sh, Scala barcha FP kontseptsiyalarini qo'llab-quvvatlaydi, Java esa ozgina qismini qo'llab-quvvatlaydi. Bu sizga naqsh solishtirish kabi juda ko'p kuchli konstruktsiyalarga kirishga imkon beradi va hokazo. Java-da mavjud bo'lgan har qanday kutubxonadan foydalanish huquqiga egasiz. Nihoyat, u JVMda ishlaydi. U Java kod bilan bir xil tezlikda ishlamasligi mumkin, ammo siz butun funktsiyani yuklash uchun bir necha mikrosaniyani sotasiz.

Foydalanish holatlari bo'yicha, yuqorida aytganlarimni kengaytirishga ijozat bering.

Agar siz UI tuzishingiz kerak bo'lsa, shubhasiz, siz OOP bilan borasiz. Bunday vaziyatda hamma narsa ob'ektdir.

Agar sizda funktsional imkoniyatlarni ulashadigan va kelajakda ko'proq yaratishni rejalashtiradigan turli xil ma'lumotlarga ega bo'lsangiz, ehtimol merosdan foydalanishingiz kerak bo'ladi. Bu sizga modulli va qayta ishlatiladigan kodni yaratishga imkon beradi. OOP bilan boring.

Agar sizda faqat bir nechta ma'lumotlar turi mavjud bo'lsa, lekin ularni bajarish uchun ko'plab operatsiyalar mavjud bo'lsa va kelajakda yangi turlarni kiritish imkoni bo'lmasa, sizga meros kerak emas. FP bilan boring.

Agar ma'lum bir operatsiyani matematik operatsiya kabi modellashtirish mumkin bo'lsa, FP bilan o'ting. Bu chalkash tuyulishi mumkin, shuning uchun men kengaytiraman. Birgalikda narsalarni qo'shadigan dastur yozishni xohlayotganingizni ayting. Buni OOP yordamida qilishingiz mumkin, ammo FPda buni qilish ancha oson. Ob'ektni tezlashtirish uchun vaqt va vaqt talab etiladi. Nega bularning barini bezovta qilyapsiz?

FP odatda matematik naqshga o'xshab ko'rinadigan operatsiyalarni modellashtirishda juda yaxshi (masalan: rekursiv usullar). Agar siz dasturni matematik isbot sifatida modellashtira olsangiz, FP-ga o'ting. Bu rostini aytsam, sizga beradigan eng yaxshi maslahat.

Ushbu paradigmalarning ikkalasi ham o'zaro bog'liq emas. Agar siz ikkalasining kombinatsiyasidan foydalansangiz, yaxshiroq dasturlarni yozishingiz mumkin. Qaysi birini ishlatishni bilishingiz kerak. Shunday qilib, tajribaga o'ting!