برنامه نویسی فانکشنال : مقایسه با شی گرایی

برای درک بهتر نوشته‌های این بخش، باید ابتدا بخش‌های زیر را مطالعه کرده باشید:

هدف شی‌گرایی چیست؟

بیایید مدل فانکشنال را با مدل شی‌گرایی مقایسه کنیم. اول از همه باید عنوان کنیم که هنوز یک تعریف واحد و جامع از شی‌گرایی وجود ندارد، و چیزهایی که در کتاب‌ها درباره آن می‌خوانید، فقط برداشت نویسنده از شی‌گرایی بوده است. اما در این متن، ما فرض را بر این می گیریم که وقتی از شی‌گرایی صحبت می‌کنیم، منظورمان همان چیزی است که در زبان‌هایی مانند سی پلاس پلاس، جاوا، سی‌شارپ، و …. با آن آشنایی دارید.

در شی‌گرایی، شما در قالب «کلاس»ها و «نمونه»ها (همان اشیا) فکر می‌کنید. یک کلاس «رفتارها» را تعریف می‌کند (به کمک متدها) و نمونه‌‌های ساخته شده از روی آن کلاس هم «وضعیت» شی را در خود نگه داری می‌کنند (به کمک فیلدها). برنامه نویس تمرکزش را روی سلسله مراتب کلاس‌ها و روابط بین اشیا قرار می دهد. وقتی به صورت شی‌گرا کدنویسی می‌کنیم، در واقع روی «وضعیت» اشیا تمرکز کرده‌ایم. بیشتر وقت ما صرف صدا زدن متدها و پاس دادن اشیا به این طرف و آن طرف خواهد شد. به تناسب صدا زدن متدها، اشیا وضعیت خود و یا حتی وضعیت بقیه اشیا را تغییر می‌دهند.

در چنین مدلی، کلاس مشخص می‌کند که یک شی چه کاری می‌تواند انجام دهد و کنترل وضعیت آن به چه حالتی خواهد بود. یکی از اهداف اصلی در چنین سیستمی «پنهان سازی» اطلاعات است. پنهان سازی اطلاعات تنها یک هدف را دنبال می‌کند و آن کنترل وضعیت شی است.

جدای از اینکه شی‌گرایی مدل مناسبی هست یا خیر، آیا تا به حال از خود پرسیده‌اید چرا به طور شی‌گرا برنامه می‌سازید؟ یا چرا شی‌گرایی اینقدر همه‌ گیر شده است؟

جملاتی مانند استفاده مجدد از کد، ساختار بهتر کدها… این حرف‌ها بیشتر جنبه‌ی تبلیغاتی دارند! فرضا استفاده مجدد از کد را در نظر بگیرید: چگونه ممکن است استفاده مجدد از یک کلاس با آن همه تشکیلاتش، در مقایسه با استفاده مجدد از یک تابع کوچک، راحت‌تر و ساده‌تر باشد؟ مشخصه‌های دیگری هم مانند «پلی‌مورفیسم»، منحصر به شی‌گرایی نیست و اتفاقا در اکثر زبان‌های فانکشنال نیز حضور دارند. پس دلیل توسعه‌ی کدها به صورت شی‌گرا چیست؟

اگر به قضیه دقت کنید، متوجه می‌شوید که هدف اصلی شی‌گرایی و تشکیلات مرتبط با آن (کلاس‌ها، اشیا، رابطه‌ها، مدل‌سازی ها، …) این است که بتوانید «وضعیت» موجودیت‌ها را در طول اجرای برنامه مدیریت کنید؛ همین! شی‌گرایی باعث می‌شود تا زبان‌های معمولی که کنترل مناسبی روی وضعیت موجودیت‌ها ندارند، بتوانند موجودیت‌ها را طوری مدل سازی کنند تا کنترل وضعیت آن‌ها آسان‌تر و قابل درک شود. و البته باید قبول کرد که شی‌گرایی تا حدی کنترل وضعیت در چنین زبان‌هایی را میسر ساخته است؛ اما وقتی بحث اعمال همروند و موازی به میان می‌آید، دیگر شی‌گرایی توان زیادی در این زمینه نخواهد داشت.

با فانکشنال بودن دیگر نیازی به شی‌گرایی ندارید

در زبان‌های فانکشنال، «وضعیت» تغییر ناپذیر است. شما نیازی ندارید که آن را کنترل کنید، «وضعیت» به طور پیش فرض از نظر منطقی کنترل شده است. بنابراین در چنین محیطی نه تنها دیگر نیازی به شی‌گرایی ندارید، بلکه کدهای شما بسیار ساده‌تر و سر راست ‌تر خواهد بود. کلاسی وجود ندارد. شی‌ای در کار نیست. لازم به مدل سازی ندارید. رابطه‌ها و وراثت اشیا وجود ندارند… فقط توابع معمولی، و داده‌های خام!

شی‌گرایی یک روش پیشنهادی برای حل مشکلی است (کنترل وضعیت) که آن مشکل از اساس در زبان‌های فانکشنال وجود ندارد! ‌بنابراین مساله اصلا این نیست که کدام یک از دیگری بهتر است، قضیه این است که در زبان‌های فانکشنال سیستم‌ای مهیا شده است که با توجه به آن، دیگر به شی‌گرایی نیازی نخواهد بود.

با توجه به بحث بالا، اگر بخواهیم شی‌گرایی را با مدل فانکشنال مقایسه کنیم به جدول زیر خواهیم رسید:

شی‌گرایی مدل فانکشنال
تعریف «کلاس»ها، به منظور مشخص کردن «رفتار»ها (متدها) و «وضعیت» (فیلدها)ی یک شی. تعریف توابع کوچک و صریح
سلسله مراتب و روابط بین اشیا کنار هم چیدن توابع کوچک، به منظور ساخت رویه‌های بزرگ تر
مدل‌سازی داده‌ها در قالب اشیا استفاده‌ی مستقیم از ساختارهای داده‌ای معمول (آرایه ها، لیست‌ها، درخت‌ها، جداول هش...)
پنهان سازی داده ها، با هدف کنترل وضعیت اشیا بدون نیاز به پنهان سازی داده‌ها، به علت تغییر ناپذیر بودن وضعیت موجودیت‌ها
در یک شی، کد و داده‌ با یکدیگر ترکیب شده می‌شود کد و داده کاملا مستقل از یکدیگر هستند

پ.ن: مرز بین شی‌گرایی و فانکشنال بودن محوتر از آنی است که بتوان زبان‌های گوناگون را با شفافیت کامل در بین آن‌ها دسته بندی کرد. می‌توان اینطور گفت که بهره بردن از پارادایم‌های مختلف برنامه‌نویسی در یک زبان، بیشتر به منطق فکری و پیش‌فرض‌های جامعه‌ی کاربری آن وابسته است. در واقع می‌توان اکثر پارادیم‌های برنامه‌نویسی را در اکثر زبان‌ها به کار برد؛ جدای از اینکه آیا زبان برای آن پارادایم به خصوص مناسب باشد یا خیر!