برنامهنویسی با استفاده از دو سبک مختلف: نگاهی عمیق به دو رویکرد برنامهنویسی شیئگرا (Object Oriented Programing) و برنامهنویسی فانکشنال (Functional Programming) برای کمک جهت انتخاب مسیر مناسب.
شما به عنوان یک مهندس نرمافزار، احتمالا با سبکها و روشهای برنامهنویسی مختلفی برخورد کردهاید که هرکدام مزایا و معایت خاص خود را دارند. یک پرسش رایج که اغلب مهندسین نرمافزار با آن روبرو میشوند این است که برای طراحی و ساخت سیستمهای نرمافزاری کدام سبک برنامه نویسی مناسبتر خواهد بود، شیئگرایی یا برنامهنویسی فانکشنال. در این مقاله تفاوتهای کلیدی میان این دو رویکرد برنامهنویسی را بررسی خواهیم کرد و مزایا و معایب متناظر با هر کدام را عنوان کرده و به شما برای تصمیمگیری جهت انتخاب مناسبترین رویکرد برنامهنویسی کمک خواهم نمود.
بیایید ابتدا این دو پارادایم برنامه نویسی را بهتر بشناسیم:
سبک برنامهنویسی فانکشنال یکی از پارادایم های برنامهنویسی است. این سبک از برنامهنویسی براساس ایده رفتار توابع در ریاضیات به عنوان تکامل توابع ریاضی شکل گرفته یا به عبارت دیگر همه چیز در این پارادایم حول توابع سازماندهی میشود. در شیوه برنامهنویسی فانکشنال، دادهها غیر قابل تغییر هستند. این به این معناست که نمیتوان آنها را پس از به وجود آمدن، تغییر داد یا به عبارتی immutable هستند. این کار، امکان بررسی و اشکالزدایی (دیباگ کردن) کدهای نوشته شده به شیوه فانکشنال را آسانتر میکند. چرا که در این روش متغیرها و تاثیرات جانبی کمتری وجود دارد.
از طرف دیگر، سبک برنامهنویسی شیئگرا، بر اساس سازماندهی کد برنامه در قالب «آبجکت های» مختلف است که این آبجکت ها نمایانگر موجودیتهای جهان واقعی و صفات و رفتارهای آنها هستند. در برنامهنویسی شیءگرا، آبجکت ها از قالبهایی تحت عنوان «کلاسها» ایجاد میشوند که این کلاسها، وضعیت[۱] (دادهها) و متدها[۲] (رفتارهای) آن آبجکت را تعریف میکنند. برنامهنویسی شیءگرا بر اساس اصول کپسوله سازی[۳]، وراثت[۴]، پلی مورفیسم[۵]، انتزاع – مفهوم – برداشت[۶] است.
اکنون که درباره این دو رویکرد مختلف در برنامهنویسی صحبت کردیم، به مزایا و معایب هر یک از این دو رویکرد میپردازیم.
یکی از مزایای برنامهنویسی فانکشنال این است که امکان نوشتن کد خوانا تر و اشکالزدایی[۷] آسان آنها فراهم میسازد. این مسئله به این دلیل است که در این رویکرد، دادهها غیرقابل تغییر بوده و اثرات جانبی موجود نیست. علاوه بر این، کدهای نوشته شده به شیوه فانکشنال نسبت به کدهای نوشته شده در رویکرد شیءگرا مختصرتر و رساتر هستند و این مسئله به مهندسین نرمافزار این امکان را میدهد که توابع مختلف را به گونهای گروهبندی کنند که امکان انجام آن در رویکرد شی گرایی وجود ندارد. در ادامه برای نمایش خصوصیات برنامهنویسی فانکشنال در مقایسه با برنامهنویسی شیءگرا مثالی را ارائه خواهم کرد.
از طرف دیگر، یکی از معایب اصلی برنامهنویسی فانکشنال این است که امکان طراحی و پیادهسازی سیستمهای واقعا پیچیده در این رویکرد چالشبرانگیزتر است. این مسئله به این دلیل است که برنامهنویسی فانکشنال نسبت به برنامهنویسی شیءگرا، دارای سطح کپسولهسازی و ماژولاریتی پایینتری است که این مسئله، امکان مدیریت تعاملها و وابستگیهای بین بخشهای مختلف سیستم را دشوارتر میسازد. علاوه بر این، فهم و نگهداری از کدهای نوشته شده به سبک برنامهنویسی فانکشنال برای مهندسانی که با این رویکرد ناآشنا هستند، دشوارتر است. یکی دیگر از معایب این رویکرد، فضای ذخیرهسازی است که این مسئله نیز به دلیل تغییرناپذیری دادهها است. رویکرد برنامهنویسی فانکشنال عموما به فضای ذخیرهسازی بیشتری نسبت به رویکرد شیءگرایی نیاز دارد.
از طرف دیگر، برنامهنویسی شیءگرا، میزان کپسولهسازی و ماژولاریتی بالاتری را برای سازماندهی کدها فراهم میآورد و بدین ترتیب، امکان مدیریت سیستمهای پیچیده را آسانتر میکند. همچنین، برنامهنویسی شیءگرا برای بسیاری از مهندسین، آشناتر و قابل درکتر است، چراکه این سبک به میزان زیادی به نحوه تفکر انسانها و تعامل آنها با موجودیتهای جهان واقعی نزدیکتر است.
گرچه، یکی از معایب اصلی برنامهنویسی شیءگرا این است که حاصل آن ممکن است کدهایی باشد که نسبت به سبک فانکشنال طولانیتر بوده و از فصاحت و رسایی کمتری برخوردار باشند، چرا که در این سبک از برنامهنویسی اشیاء و کلاسها باید ایجاد و مدیریت شوند. این مسئله نیز در مثالی که بعدا ارائه میکنم نشان داده خواهد شد. علاوه بر این، نگهداری و اشکالزدایی کدها در سبک برنامهنویسی شیءگرا ممکن است چالشبرانگیزتر باشد چراکه اثرات جانبی بالقوهای در این رویکرد موجود هستند و وضعیت اشیاء باید به دقت مدیریت شود.
بیایید نگاهی به تاریخچه این رویکردهای برنامهنویسی بیاندازیم:
برنامهنویسی شیءگرا نسبت به برنامهنویسی فانکشنال بسیار گستردهتر بوده و بیشتر مورد استفاده قرار گرفته است. ممکن است فکر کنید این مسئله به این دلیل است که برنامهنویسی شیءگرا قدیمیتر از برنامهنویسی فانکشنال است، اما این مسئله صحت ندارد. برنامهنویسی فانکشنال قبل از برنامهنویسی شیءگرا عرضه شده است.
جان مککارتی اولین زبان برنامهنویسی فانکشنال سطحبالا را خلق نموده است. این زبان لیسپ (LISP) نام دارد و در آواخر دهه ۱۹۵۰ برای کامپیوترهای بخش علوم دانشگاه MIT که از سری IBM 700-7000 بودهاند، توسعه داده شده است.
از طرف دیگر، برنامهنویسی شیءگرا (OOP) به وسیله آلن کیکرا درسال ۱۹۶۶ یا ۱۹۶۷ و زمانی که او در دبیرستان مشغول به تحصیل بود، ابداع شده است. برنامه کاربردی Sketchpad توسط Ivan Sutherland یکی از برنامههایی اولیهای بوده است که به شیوه شیءگرایی طراحی شد است.
همانطور که مشاهده میکنید، این دو سبک از برنامهنویسی ۱۵ سال با هم فاصله دارند.
علاوه بر زبان برنامهنویسی lisp، دو زبان Erlang و Heskell نیز از جمله زبانهای برنامهنویسیای هستند که براساس رویکرد فانکشنال طراحی شدهاند. همچنین میتوانیم برای برنامهنویسی شیءگرا، زبانهای برنامهنویسی شناخته شده java، C# و RUST را نیز نام ببریم.
اما اکنون این سوال پیش میآید که چرا سبک برنامهنویسی شیءگرا به این میزان گسترده است؟
برنامهنویسی شیءگرا بنا بر دلایلی نسبت به سبک برنامهنویسی فانکشنال به میزان بیشتری مورد استفاده قرار گرفته است:
یکی از این دلایل این است که برنامهنویسی شیءگرا اغلب برای برنامهنوسیان مختلف آشناتر و قابل فهمتر است، به ویژه برای برنامهنویسان سنتی که دارای پیشزمینههایی از سبک برنامهنویسی رویهای[۸] هستند. امکان استفاده از اشیاء، کلاسها و وراثت در برنامهنویسی شیءگرا امکان تفکیک واضح نگرانیها را فراهم آورده و راهی طبیعی برای سازماندهی و ساختاربندی کدها است.
یکی دیگر از این دلایل این است که برنامهنویسی شیءگرا اغلب برای مدلسازی مسائل و سیستمهای واقعی که ممکن است پیچیده و پویا نیز باشند، مناسبتر است. کپسولهسازی و پولی مورفیسم در برنامهنویسی شیءگرا امکان نوشتن کدهایی انعطافپذیر و قابل توسعه مجدد[۹] را فراهم میآورد و استفاده از این رویکرد را در پروژههای بزرگ و درحال تکامل مناسب میکند.
علاوه بر این، برنامهنویسی شیءگرا به شدت به وسیله زبانهای برنامهنویسی محبوب پشتیبانی شده و اغلب کتابخانهها، فریمورک ها و ابزارها بر اساس مفهوم شیءگرایی ساخته شدهاند و کامیونیتی بسیار بزرگی دارد. به همین دلیل، استفاده از این رویکرد برای بسیاری از مهندسین نرم افزار کاربردیتر است.
اجازه دهید مثالی از یک برنامه ساده را به هر دو شیوه شیءگرا و فانکشنال بررسی کنیم:
این برنامه به شیوه برنامهنویسی فانکشنال و با استفاده از زبان برنامهنویسی Scala نوشته شده است و کار آن این است که پس از دریافت شعاع یک دایره، محیط و مساحت آن را محاسبه میکند. این برنامه از دو فانکشن (محیط و مساحت) برای محاسبه محیط و مساحت دایره استفاده کرده و هیچ وضعیت خارجیای را تغییر نداده و هیچ اثر جانبی ندارد و همانطور که مشاهده میکنید، درمقایسه با سبک شیءگرای خود، از رسایی بالاتری برخوردار است.
این برنامه مثالی ساده از یک برنامه شیءگرا است که یک کلاس دایره را همراه با یک متد سازنده[۱۰] و دو متد نمونه (محیط و مساحت) تعریف میکند. کلاس دایره نمایانگر یک دایره با یک شعاع، متد محیط که کار آن محاسبه محیط دایره بوده و متد مساحت که کار آن محاسبه مساحت دایره است، میباشد. برای استفاده از کلاس دایره، یک آبجکت با نام c (یا نمونه (instance)) از آن ایجاد کرده و دو متد محیط و مساحت را برای محاسبه محیط و مساحت دایره c فراخوانی میکنیم.
همان طور که مشاهده میکنید و پیشتر نیز عنوان کردم، برنامهنویسی شیءگرا برای این مثال، نسبت به برنامه نوشته شده با استفاده از رویکرد فانکشنال طولانی تر است. همچنین میتوانید سطح کپسولهسازی در این برنامه را خودتان مشاهده کنید.
بنابراین، استفاده از کدام یک از این دو رویکرد برای برنامهنویسی مناسبتر است؟
حقیقت این است که هیچ گونه پاسخ مناسب و دقیقی برای این سوال وجود ندارد. بهترین رویکرد با توجه به نیازهای شما، به الزامات خاص پروژه شما و ترجیحات و مهارتهای تیم توسعه شما بستگی دارد.
با توجه به این مسئله، بهتر است با سبک برنامهنویسی شیءگرا و فانکشنال و سایر شیوههای برنامهنویسی آشنا باشید. این مسئله، سبب میشود که محدوده وسیعی از ابزارها و روشها را به هنگام طراحی و ساخت سیستمهای نرمافزاری در اختیار داشته باشید.
میدانم که ممکن است با این پاسخ من ناامید و ناراحت شده باشید، اما این یک حقیقت است. باید برای حل مسئله و مشکل خود راهحل درست را انتخاب کنید. اما در اینجا یک قانون سرانگشتی و نتیجه گیری در مورد انتخاب بین سبکهای فانکشنال و شیءگرایی وجود دارد:
برنامهنویسی شیءگرا و فانکشنال دو سبک برنامهنویسی قدرتمند و رایج هستند که هر کدام دارای مزیتها و معایب خود میباشند. با این که میتوان با استفاده از رویکرد برنامهنویسی فانکشنال، به شیوهای آسانتر کدهایی مفصل و رسا نوشت که استدلال و اشکالزدایی آن آسان است، با این وجود، طراحی و پیادهسازی سیستمهای پیچیده با استفاده از این رویکرد ممکن است چالشبرانگیزتر باشد.
از طرف دیگر، برنامهنویسی شیءگرا، میزان کپسولهسازی و ماژولاریتی بالاتری را برای سازماندهی کدها فراهم میآورد و بدین ترتیب، امکان مدیریت سیستمهای پیچیده را آسانتر میکند. گرچه، برنامهنویسی شیءگرا ممکن است نسبت به برنامهنویسی فانکشنال طولانیتر بوده و از رسایی کمتری برخوردار باشد. علاوه بر این، نگهداری و اشکالزدایی کدها در سبک برنامهنویسی شیءگرا ممکن است چالشبرانگیزتر باشد چراکه اثرات جانبی بالقوهای در این رویکرد موجود هستند و وضعیت آبجکت ها باید به دقت مدیریت شود.
برنامهنویسی فانکشنال اخیرا به دلیل ظهور مفهوم کلانداده و سیستمهای مبتنی بر فضای ابری درحال کسب محبوبیت است. برنامهنویسی فانکشنال برای پردازش موازی و همزمان[۱۱] و و همچنین برای پردازش داده متدوام[۱۲]، محاسبات علمی[۱۳]، یادگیری ماشین[۱۴]، و سایر وظایف مرتبط مناسب است. با این حال، برنامهنویسی شیءگرا، معمولاً در بسیاری از پروژههای صنعتی و سازمانی مورد استفاده قرار میگیرد و همچنان انتخاب رایجتری برای توسعه برنامه های تحت وب، رابط کاربری گرافیکی، بازیهای ویدیویی، شبیهسازی[۱۵]، نرمافزار پیچیده، مدلسازی، آموزش و یادگیری است.
برای یک مهندس نرمافزار خوب، داشتن درک عمیقی از هر دو رویکرد فانکشنال و شیءگرایی و سایر سبکهای برنامهنویسی جهت انتخاب مناسبترین آنها ضروری است. با بهروز ماندن از آخرین روندها و فناوریهای موجود در این حوزه و بهبود پیوسته مهارتها و دانش خود میتوانید اطمینان حاصل کنید که ابزارها و تخصص مورد نیاز را جهت ساخت سیستمهای نرمافزاری با کیفیت بالا که نیازهای کاربران شما را برآورده میکنند، دراختیار خواهید داشت.
[۱] State [۲] Behaviors [۳] Encapsulation [۴] Inheritance [۵] Polymorphism [۶] Abstraction [۷] Debugging [۸] Procedural [۹] Reusability [۱۰] Constructor [۱۱] Parallelism [۱۲] Stream Processing [۱۳] Scientific Computation [۱۴] Machine learning [۱۵] Simulation
دیدگاه خود را بنویسید