این پست ترجمه بخشی از مقاله "Object-Oriented Programming — The Trillion Dollar Disaster" از Medium است. مقاله اصلی خیلی طولانی بود . به همین خاطر مجبور شدم ان را به چند بخش تقسیم کنم.
اگر قسمت اول(مقدمه) را نخوانده اید چیزی را از دست نداده اید ولی چیز های خوبی در ان روشن میشود.
برنامه های شی گرا به عنوان جایگزین چیز های درست به کار میرود... Edsger W. Dijkstra
برنامه نویسی شی گرا با یک هدف در ذهن خلق شد - کنترل پیچیدگی کد های رویه ای(procedural).
به عبارت دیگر, قرار بود سازماندهی کد را بهتر کند. هیچ دلیل و شواهدی وجود ندارد که برنامه نویسی شی گرا بهتر از برنامه نویسی رویه ای ساده است.
حقیقت تلخ این است که OOP از انجام تنها وظیفه اش (که برای ان ایجاد شده) ناکام مانده است. روی کاغذ خوب به نظر می آید -- ما سلسله مراتبی تمیز از حیوانات, سگ ها و انسان ها و ... داریم. با این حال وقتی پیچیدگی برنامه شروع به افزایش میکند شکست میخورد. به جای کاهش پیچیدگی, وضعیت ناپایدار را بی پروا تشویش میکند و با الگو های طراحی بیشمارش پیچیدگی اضافه تولید میکند. OOP کار های معمولی توسعه مانند refactoring و testing را بی دلیل سخت میکند.
شاید بعضی ها با من مخالف باشند , اما حقیقت این است که OOP مدرن در java و C# احتمالا هیچوقت طراحی نشده اند. هیچوقت از یک موسسه تحقیقاتی معتبر منتشر نشده اند. جبر لامبدا(ویکی پدیا) یک پایه علمی کامل از برنامه نویسی functional اراعه میدهد. OOP هیچ تطابقی با ان ندارد.
برنامه نویسی شی گرا ظاهرا در کوتاه مدت معصوم است . ولی عواقب طولانی مدت OOP چست؟ OOP یک بمب ساعتی است, منتظر انفجار میماند تا کد به اندازه کافی بزرگ شود.
برنامه نویسی شی گرا برای ذهن ما طبیعی نیست, فرایند فکری ما روی "انجام" کار ها متمرکز است -- صحبت کردن با دوستان , خوردن پیتزا. مغز ما برای انجام کار ها تکامل یافته , نه سازمان دادن جهان در سلسله مراتب های پیچیده از کلاس ها مجرد.
برنامه نویسی شی گرا غیرقطعی است-- برخلاف برنامه نویسی functional , تضمینی وجود ندارد که به ازای ورودی ها یکسان خروجی های مشابه بگیریم. این , استدلال در مورد برنامه را خیلی سخت میکند. به عنوان یک مثال ساده : خروجی ۲+۲ یا calculator.Add(2, 2) معمولا برابر چهار است, اما گاهی اوقاط ممکن است سه , پنج یا حتی ۱۰۰۱ باشد. وابستگی های (dependencies) شی calculator ممکن است نتیجه محاسبه را به شکل محسوس اما عمیقی تغییر دهد .
برنامه نویسان خوب کد خوب مینویسند و برنامه نویسان بد کد بد مینویسند, الگو برنامه نویسی اهمیتی ندارد. با این حال, الگو برنامه نویسی بد , ممکن است برنامه نویس بد را مجبور به ایجاد خسارات زیاد کند. البته, این شما نیستید, تاوقتی که این مقاله را میخوانید و تلاش میکنید که یاد بگیرید. برنامه نویسان بد هرگز برای یادگیری وقت ندارند, آنها فقط مثل دیوانه ها چند دکمه تصادفی را فشار میدهند. چه بخواهید چه نخواهید, شما با برنامه نویسان بد کار خواهید کرد, بعضی از انها خیلی خیلی بد هستند. و , متاسفانه, OOP محدودیت های لازم برای جلوگیری از برنامه نویسان بد به ایجاد خسارت های زیاد را ندارد.
فکر نمیکنم برنامه نویس بدی باشم, اما بدون یک چهارچوب قوی که کارم را روی ان بنا کنم نمیتوانم کد خوب بنویسم. بله , چهارچوب هایی وجود دارد که خود را با مشکلات خیلی خاص نگران میکنند( مثل Angular or ASP.Net) .
من در مورد چهارچوب های برنامه نویسی صحبت نمیکنم. من در مورد تعریف فرهنگ لغت از چهارچوب حرف میزنم:"یک ساختار حمایتی ضروری و اساسی" -- چهارچوب هایی که خود را با چیز هایی مفهومی تر مثل "سازماندهی کد" و "مقابله با پیچیدگی کد" نگران میکنند.گرچه برنامه نویسی شی گرا و functional هر دو الگوی برنامه نویسی هستند ، هر دو چارچوب بسیار سطح بالایی هم هستند.
سی ++ یک زبان [شی گرا] وحشتناک است... و محدود کردن پروژه تان به C به این معناست که مردم با "مدل -- object model" های احمقانه گیج نمیشوند . -- لینوس توروالدز , خالق لینوکس
لینوس توروالدز به طور گسترده ای با انتقاد های ازادش از C++ و OOP شناخته میشود. چیزی که او ۱۰۰٪ درمورد ان درست میگفت , محدود کردن برنامه نویسان در انتخاب هایی که میتوانند بکنند است. در حقیقت هرچه انتخاب های برنامه نویس کمتر باشد , برنامه انعصاف پذیر تر میشود. در نقل و قول بالا , لینوس توروالدرز به شدت به داشتن یک چهارچوب خوب برای بنا کردن کدمان بر اساس ان پیشنهاد میکند.
خیلی ها با محدودیت سرعت در جاده ها مخالف هستند, اما انها برای جلوگیری از تصادف و مرگ ضروری هستند. به همین ترتیب ، یک چارچوب خوب برنامه نویسی باید سازوکارهایی را فراهم کند که مانع از انجام کارهای احمقانه شود.
یک چهارچوب خوب برنامه نویسی به ما کمک میکند کد قابل اعتماد بنویسیم. در درجه اول , باید با فراهم کردن چیز های زیر , به کم کردن پیچیدگی کمک کند.
متاسفانه , OOP ابزار ها و انتخاب های زیادی را در اختیار برنامه نویس قرار میدهد, بدون اینکه نوع درست محدودیت را تحمیل کند. با اینکه OOP قول پرداختن به modularity و بهبود قابلیت استفاده مجدد (reusability) را داده , اما نتوانسته به وعده های خود عمل کند( بعدا در مورد این بیشتر صحبت میکنم). کد OOP انتشار وضعیت ناپایدار را تشویق میکند , که بار ها و بار ها ثابت شده که ناامن است. OOP معمولا مقدار زیادی کد تکراری و بیهوده نیاز دارد (boilerplate code).
برنامه نویسی functional دقیقا چیست؟ عده ای فکر میکنند یک الگو برنامه نویسی بسیار پیچیده است که فقط در دانشگاه ها کاربرد دارد و برای "دنیای واقعی" مناسب نیست. این از حقیقت دور نیست!!
بله . برنامه نویسی functional یک اساس ریاضی قوی دارد که ریشه ها ی ان به حساب لامبدا برمیگردد.(lambda calculus) . با این حال , بیشتر ایده هایش به عنوان پاسخی بر ضعف های زبان های برنامه نویسی اصلی ظهور میکند. توابع مفاهیم اصلی برنامه نویسی functional هستند. وقتی درست استفاده شوند , توابع سطحی از modularity و reusability را به وجود می اورد که هرگز در OOP مشاهده نشده. حتی دارای الگو های طراحی ای است که به مشکلات nullability میپردازد و روشی برتر برای رسیدگی به خطا ها اراعه میکند.
چیزی که برنامه نویسی functional در ان واقعا خوب عمل میکند این است که به ما کمک میکند نرم افزار قابل اعتماد بنویسیم. نیاز به دیباگ کردن به طور کامل از بین میرود. بله, نیازی نیست قدم به قدم روی کد پیش بروید و متغیر ها را چک کنید! شخصا مدت زیادی است که دیباگر را لمس نکرده ام.
بهترین قسمت ؟ اگر میدانید چطور از توابع استفاده کنید شما یک برنامه نویس functional هستید. فقط باید یاد بگیرید که چطور بهترین استفاده را از توابع کنید.
من برنامه نویسی functional را موعظه نمیکنم, حتی اهمیت نمیدهم که از کدام الگو برنامه نویسی استفاده میکنید.من فقط تلاش میکنم مکانیسم هایی که برنامه نویسی functional برای رفع مشکلات ذاتی OOP اراعه میکند را به شما انتقال دهم.