برنامهنویسی شئگرا (Object Oriented Programming) که به اختصار OOP نیز نامیده میشود، در حقیقت نوعی منطق یا الگوست که برگرفته از زندگی روزمرهی ما بوده و حدودا در دههی 1960 میلادی مطرح شده است، در ادامه با رویاسایت همراه باشید تا بیشتر با مفاهیم برنامهنویسی شئ گرا آشنا شویم.
در این مقاله میخواهم در مورد یک نوع پرسش مشابه در دنیای برنامهنویسی صحبت کنم:
مفاهیم و اصول اساسی برنامهنویسی شیءگرا چیست؟
این پرسش پرتکرار در مصاحبههای شغلی برنامهنویسی است و نمیتوانید آن را نادیده بگیریم. وقتی به دنبال کار میگشتم این پرسش از من هم پرسیده شده و بعدها خودِ من هم در مصاحبهها از متقاضیان کار آن را پرسیدهام.
بیشتر توسعهدهندگان تازهکار و کمتجربه باید به این پرسش پاسخ دهند. زیرا پاسخ به این پرسش سه نکته را برای مصاحبهکنندگان آشکار میکند:
۱- آیا داوطلب از قبل برای مصاحبه آمادگی داشته؟
به طور معمول اگر بیدرنگ پاسخ پرسش مطرح شده را بدهید، امتیاز بیشتری میگیرید.
۲- آیا داوطلب آموزشهای لازم را دیده است؟
این که بتوانید اصول برنامهنویسی شیءگرا را بگویید، نشان میدهد که شما پیش از این آموزشهایی که لازم بوده را دیدهاید، از مرحلهی paste ـ copy عبور کرده و به مسائل از چشمانداز بالاتری نگاه میکنید.
۳- درک داوطلب سطحی است یا عمیق؟
در نظر مصاحبهکنندگان، این که چقدر خوب به این سوال بدهید با کیفیت پاسخگویی شما به موارد دیگر برابر است. باور کنید!
چهار اصل و مفهوم مهم برنامه نویسی شیءگرا (OOP) عبارتند از: کپسوله کردن (encapsulation)، انتزاع (abstraction)، ارث بری (inheritance) و چند ریختی (polymorphism).
برای برنامه نویسان کمتجربه شاید این واژهها، کمی ترسناک به نظر برسند و توضیحات پیچیده و بیش از حد طولانی ویکیپدیا هم ممکن است سبب سردرگمی بیشتر آنها شود.
به همین خاطر است که ما میخواهیم برای هر کدام از این موارد، توضیحی ساده، کوتاه و واضح ارائه دهیم.
(encapsulation)کپسولهکردن
فرض کنید یک برنامه داریم و همچنین فرض کنید که بر اساس قوانین تعریف شده، در این برنامه چند شیء وجود دارند که از نظر منطق با هم تفاوت دارند.
کپسولهکردن زمانی تحقق پیدا میکند که هر یک از این شیها حالت خصوصی (private) خود را در داخل کلاس حفظ کند و دیگر شیها دسترسی مستقیم به آن نداشته باشند. در عوض هر یک از آنها بتوانند فهرستی از توابع عمومی (public) را (در قالب متدها) فراخوانی کنند.
به این ترتیب، وضعیت هر یک از این شیءها با استفاده از متدها مدیریت میشود و هیچ کلاس دیگری نمیتواند به آن شیء دسترسی داشته باشد مگر این که به طور واضح و با صراحت چنین اجازهای به آن داده شده باشد. پس اگر بخواهید یکی از چنین شیءهایی را مورد استفاده قرار دهید، این کار با استفاده از متدهای موجود امکانپذیر خواهد بود. اما (به طور پیشفرض) نمیتوانید بدون واسطه حالت آن را تغییر دهید.
(abstraction) انتزاع
انتزاع را میتوان یک توسعهی ذاتی کپسولهکردن در نظر گرفت. در طراحی شیگرا، برنامهها اغلب بسیار بزرگ است و شیهای جداگانه با یگدیگر بسیار در ارتباط هستند. بنابراین، نگهداری چنین پایگاه کد بزرگی برای چندین سال، که به مرور تغییراتی نیز در آن اعمال خواهد شد، بسیار سخت است.
هدف مفهوم انتزاع، آسان کردن این مشکل است.
انتزاع به این معنی است که برای استفاده از هر شیء تنها ساز و کار سطح بالای آن نشان داده شود. این ساز و کار باید جزئیات پیاده سازی داخلی را پنهان کند و تنها عملیات مرتبط با سایر شیءها را نشان بدهد.
استفاده از این ساز و کار باید آسان باشد و در طول زمان به ندرت دچار تغییر شود. این ساز و کار را میتوان مجموعهی کوچکی از متدهای عمومی در نظر گرفت که هر کلاس دیگری بدون اینکه بداند چگونه آنها کار میکنند، بتواند از آنها استفاده کند.
یک دستگاه قهوهساز را در نظر بگیرید. این دستگاه در زیر پوشش خارجی خود، کارهای زیادی انجام میدهد و صداهای عجیبی ایجاد میکند. با این حال، برای استفاده از آن فقط باید قهوه را داخل آن بریزید و دکمه دستگاه را فشار دهید.
(inheritance) ارث بری
در دو بخش قبل، دیدیم که کپسولهکردن و انتزاع چگونه میتوانند به ما در توسعهی و نگهداری یک پایگاه کد گسترده کمک کنند.
اما آیا میدانید یکی دیگر از مشکلات رایج در طراحی OOP چیست؟ این که شیها اغلب بسیار باهم شباهت دارند. همهی آنها یک منطق مشترک دارند اما به طور کامل شبیه به هم نیستند.
با این توضیح، چطور میتوانیم هم از آن منطق مشترک بهره ببریم و هم منطق منحصر به فردی را در یک کلاس مجزا جای دهیم؟ یکی از راههای دستیابی به این هدف، ارثبری است.
ارث بری به معنی مشتق کردن یک کلاس از کلاس دیگر است. در اصطلاح، کلاس اولیه را parent یا والد و کلاس مشتق شده از کلاس اولیه را child یا فرزند مینامند. به این ترتیب یک سلسله مراتب به وجود میآید که در آن فرزندان از والد خود ارث میبرند.
کلاس فرزند از همهی فیلدها و متدهای کلاس والد استفاده میکند (بخش مشترک) و علاوه بر آن، میتواند فیلدها و متدهای مخصوص به خود را نیز داشته باشد (بخش غیر مشترک).
(polymorphism) چند ریختی
در زبان یونانی کلمهی polymorphism به معنی اشکال متعدد است.
ما قدرت ارث بری را می شناسیم و خوشبختانه از آن استفاده میکنیم. اما مشکل دیگری وجود دارد. فرض کنید یک کلاس والد داریم و چندین کلاس فرزند که از آن ارث میبرند. گاهی لازم است که از مجموعهای ـ برای مثال یک لیست ـ شامل تمام این کلاسها استفاده کنیم یا ممکن است بخواهیم از متدی که در کلاس والد به کار بردهایم در کلاسهای فرزند نیز استفاده کنیم.
این موضوع را میتوان با استفاده از چند ریختی حل کرد.
به زبان ساده، چند ریختی راهی برای استفاده از یک کلاس، درست مانند کلاس والد آن است به طوری که تنوع شیءها سبب به هم ریختگی و اختلال نشود. در عین حال، هر کلاس فرزند متدهای اختصاصی خود را نیز پیادهسازی میکند.
این کار اغلب با تعریف یک رابط (والد) برای استفادههای مجدد، انجام میشود. در این رابط مجموعهای از متدهای مشترک تعریف میشود. سپس هر یک از کلاسهای فرزند نسخهی ویژهی خود از این متدها را پیادهسازی میکند.
بنابراین، هر وقت در یک مجموعه (برای مثال یک لیست) و یا متد به یک نمونه (instance) از والد نیاز باشد، زبان بدون در نظر گرفتن اینکه نیاز از سوی کدام کلاس فرزند مطرح شده است، بر ارزیابی اجرای صحیح متد مشترک مورد نظر تمرکز میکند.
مزایای برنامهنویسی شئگرا چیست؟
هرچند برنامهنویسی شئگرا در ابتدا شاید کمی پیچیده به نظر برسد و نیاز به تجزیه تحلیلهای اولیهی برای پیادهسازی برنامه داشته باشد، اما در دراز مدت و در مراحل تست و نگهداری برنامه به شدت به کمک شما خواهد آمد، از ویژگیهای برنامهنویسی شئگرا میتوان به موارد زیر اشاره کرد:
- افزایش امنیت برنامه
- کاهش هزینه نگهداری
- قابلیت استفاده مجدد
- تحلیل سادهتر برنامه
همانطور که در ابتدای مقاله گفتیم برنامهنویسی شئگرا به شدت به دنیای واقعی ما شباهت دارد و معمولا سادهتر توسط ذهن درک میشود، بنابراین سعی کنید تا حد ممکن برنامههای خود را با استفاده از اصول شئگرایی نوشته و به دنیای برنامهنویسان حرفهای نزدیکتر شوید.