Sam Aghapour
Sam Aghapour
خواندن ۹ دقیقه·۳ سال پیش

صفر تا صد oop در جاوااسکریپت! قسمت دوم: 4 اصل oop

object-oriented programming
object-oriented programming

سلام دوستان?

توی مقاله قبلی ورود به دنیای oop یا برنامه نویسی شی گرا در جاوااسکریپت رو با یادگرفتن مبحث prototype و class ها شروع کردیم و توی این قسمت قصد داریم که این ماجراجویی رو با یاد گرفتن چهار اصل مهم در برنامه نویسی شی گرا ، تموم کنیم.

قبل از شروع اصول شاید بپرسین برنامه نویسی شی گرا ینی چی اصلا؟؟!

برنامه نویسی شی گرا یا object-oriented programmin ، یک الگو بر پایه آبجکت ها هستش. ینی یه روش یا الگو از کد زدن که توش سر و کارمون با آبجکتی هست که دارای دیتا یا به اصطلاح پراپرتی و متد هایی هستند و از روی اون آبجکت، آبجکت های دیگه رو میسازیم.حالا به اون کلاسی که از روش ابجکت میسازیم و دارای متد و پراپرتی هستش bluprint میگن که به معنای "طرح" هم هستش و به آبجکتهای ساخته شده از اون instance میگن که به معنای "نمونه" یا "مثال" هستش و توی قسمت اول باهاشون آشنا شدیم و اگه بخوام یه مثال از دنیای واقعی بزنم ماشین یه آبجکت هستش که دارای کلی متد و پراپرتی مثل گاز دادن، ترمز کردن، بوق زدن و... هست یا مثلا انسان یه ابجکت هست که دارای متد و پراپرتی هایی مثل قد و وزن و رنگ چشم و... هست.


4 اصل یا ستون برنامه نویسی شی گرا
4 اصل یا ستون برنامه نویسی شی گرا

1. اصل اول: ENCAPSULATION یا کپسوله سازی

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

کپسوله کردن
کپسوله کردن

توی مثال بالا اول اومدیم متد هارو توی اسکوپ گلوبال خیلی آزاد و رها نوشتیم و الان بدیش اینه که هر کس و ناکسی هر جا میتونه به با یه کلمه ()start نوشتن بهش دسترسی داشته باشه اما توی راه دوم ما کپسوله سازی کردیم و ریختیمشون داخل ابجکت car تا همه بدونن که آقا فقط اینا فقط مربوط به ماشینه شما برای چیزایی مثل خوش آمد گویی نباید از این متد ها استفاده کنی!

البته تعریف کپسوله کردن رو به همینجا بسنده نمیکنیم، توی اصل encapsulation ما عملا متد ها و پراپرتی های مرتبط به هم رو میریزیم داخل یه ابجکت و میگیم که این متدا اماده اینجا هستند و هر آبجکتی که از این ابجکت نمونه سازی شد میتونه راحت به این دسترسی داشته باشه و استفادش کنه.در واقع اینطوری هم میشه گفت که هدف اصلی encapsulation ، جمع کردن همه ی متدا و پراپرتی های مرتبط توی یه ابجکت و غیر قابل دسترس مستقیم کردنشون هست و با متد های getter , setter ای که تعریف میکنه میتونید به فلان پراپرتیش دسترسی داشته باشید که البته توی عکس بالا به این اشاره نشد. مثال از چیزی که گفتم:

دسترسی یا دستکاری مستقیم ممنوع
دسترسی یا دستکاری مستقیم ممنوع

توی عکس بالا اگه پراپرتی های name و speed رو کپسوله نمیکردیم همه جا و همه جوره قابل دسترس بود و میشد با لاگ گرفتن name یا speed مستقیما بهش دسترسی داشت اما وقتی کپسوله میکنیمشون باید یه مقداری رو با فانکشن setter ای که تعیین شده بهش بدیم و بعد با فانکشن getter مقدارشو بگیریم.

توی عکس بالا که مثالی از ماشین در دنیای واقعی هست ، ماشین یه ابجکته که همه ی پراپرتی هایی مثل بدنه و چرخ و موتور و همه متدهایی مثل حرکت و خاموش و روشن شدن و... رو توی خودش داره و ما فقط کافیه صداش بزنیم و کپسوله کردن میگه میخوای ماشینو روشن کنی؟ متد start رو صدا بزن و حالشو ببر.

نتیجه: اصل ENCAPSULATION، پیچیدگی کد رو با زیر یه چتر(ابجکت) بردن دیتای مرتبط کمتر میکنه و از دسترسی مستقیم داشتن به این دیتا در محوطه بیرونی در جهت بالا بردن امنیت این دیتا (پراپرتی و متدها) جلوگیری میکنه.

2. اصل دوم: ABSTRACTION یا تفکیک و یا انتزاع

این اصل کارش اینه که اطلاعات غیر ضروری رو مخفی میکنه و فقط چیزای ضروری رو نشون میده ینی شما نیازی نیست بدونی متد استارت یا بوق زدن چه پروسه ای رو طی میکنه تا نتیجه رو برگردونه و فقط متد رو صدا میکنی و استفادش میکنی.

abstraction: show essentials and hide unnecessarily data
abstraction: show essentials and hide unnecessarily data

توی عکس بالا راننده به این فکر نمیکنه که وقتی پدال رو فشار میده "چگونه" ماشین حرکت میکنه و فقط اینو میدونه که با فشار دادن پدال گاز(یا صدا زدن متد حرکت) این ماشین قراره "چه کاری" رو انجام بده


مثالش توی کد:

صدا زدن استارت بدون توجه به اینکه چجوری کار میکنه
صدا زدن استارت بدون توجه به اینکه چجوری کار میکنه

توی مثال بالا میبینیم که ما کاری نداریم متد استارت "چجوری" کار میکنه که "...starting" نمایش داده میشه، ما فقط میدونیم که با صدا زدن قراره "چی" نشون بده و abstraction همینه

و موضوع دیگه اینکه با پرت کردن ارور (throw new Error) داخلِ هر متدی داریم صراحتا میگیم که نمیتونی از این متد بدون رونویس کردنش برای هر نمونه ابجکت استفاده کنیم و باید بگی این متد برای هر ابجکت چی برمیگردونه و همینطور نمیتونی از خود ابجکت Car به طور مستقیم استفاده و ازش نمونه بسازی و فقط با فرزنداش میتونی اینکارو بکنی. اما چرا باید برای بعضی متدا ارور پرت کنه تا مجبور بشی رونویسش کنی ؟؟

سوال خوبیه . جوابش:

فرض کنید ما متدی مثل start که نیازی به بازنویسیش هم نداریم برای همه صدا میزنیم و یکسانه اما اگه بخوایم بگیم که تسلا استارتش یه فرقایی با ولوو و مابقی ابجکت های نمونه داره مجبوریم متد استارت رو از توی Car تغییر بدیم که اینطوری این تغییر روی همه ی ابجکت ها اعمال میشه ! و ما نمیخوایم این اتفاق بیفته و میخوایم که اون متد فقط برای اون ابجکت بازنویسی بشه پس در مثال بالا هم سوخت ماشین تسلا با بقیه ماشینا فرق داره همشون گازی هستن و تسلا برقی! پس نمیتونیم اون متد رو به همشون اعمال کنیم چون در این صورت یا همه باید برقی بشن یا همه از حمله تسلا باید با بنزین سوختشون تامین شه.

نتیجه : اصل ABSTRACTION ، "چگونه انجام شدن" را مخفی و "چه چیزی انجام شدن" رو نمایش میده، پیچیدگی رو کم میکنه ، از تاثیرِ تغییراتِ متدها روی همه ی ابجکت ها جلوگیری میکنه.

3. اصل سوم: INHERITANCE یا وراثت

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

به ارث بردن حرکت و توقف و... از یک ماشین توسط انواع مدل های ماشین
به ارث بردن حرکت و توقف و... از یک ماشین توسط انواع مدل های ماشین

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


مثالش توی کد:

به ارث بردن متد start, stop و مشخص کردن سوخت منحصر بفرد برای هر ماشین
به ارث بردن متد start, stop و مشخص کردن سوخت منحصر بفرد برای هر ماشین

در مثال بالا ما یه ابجکت Car داریم که دارای متد هایی مثل حرکت و توقف هست و یه ابجکت تسلا داریم که این متد هارو به ارث برده تا ما دوباره نیاز نباشه از صفر بنویسیمشون و متد منحصر بفرد خودش ینی getPower هم داره که بهش سوخت منحصر بفرد خودشو میده و حالا میتونیم مدل های مختلف تسلا رو با نمونه سازی از این ابجکت بسازیم و برای ولوو هم دقیقا همین پروسه اس.ما برای هیچ کدوم از این مدلا استارت رو تعریف نکردیم اما میبینیم که با صدا زدن استارت همشون میدونن چیکار باید بکنن چون به ارث بردنش.

نتیجه: اصل INHERITANCE، از چند باره نویسیِ متد ها و اشغال حافظه جلوگیری میکنه ، پیچیدگی کد رو کمتر میکنه و متدهامون رو قابل استفاده مجدد میکنه.

4.اصل چهارم: POLYMORPHISM یا چند شکلی یا چند فرمی

اصل آخر اینطوریه که اگه ما قراره از یه ابجکت متدهایی رو به ارث ببریم، متدهایی که لازمه، تواناییِ بازنویسی داشته باشن تا بدون تعریف کردن اون متد برای هر ابجکت و اشغال فضای بیشتر فقط خروجیش رو تغییر بدیم.

و همچنین با از صفر نوشتن متد برای هر ابجکت علاوه بر اشغال فضای بیشتر ، پایین اومدن پرفورمنس و پیچیدگی و شلوغی یه اشکال دیگه هم داره اونم قابلیت نگهداری رو از بین میبره ینی شما اگه بخوای یه چیزی رو توی عملکرد این متد تغییر بدی باید توی همه ی این ابجکت ها اضافه کنی و حالا فرض کن بیشتر از هزارتا ابجکت داشته باشی که در اینصورت علاوه بر پرفورمنس به خاااره انگشتات هم یه سلامی میرسه :)

مشترک بودن فرمون تو همه ماشین ها اما متفاوت بودن شکل و نرم بودنش توی هر ماشین
مشترک بودن فرمون تو همه ماشین ها اما متفاوت بودن شکل و نرم بودنش توی هر ماشین

توی عکس بالا ما فرمون رو توی همه ی ماشین ها به ارث بردیم اما تفاوتش توی هر ابجکت اون نرم بودن و شکل و قیافه اش هست مثلا فرمون پورشه و پراید جفتشون فرمون دارند اما آیا این دو کاملا مشترک و شبیه به هم هستند؟ :)


مثالش تو کد:

همه ی ابجکت ها متد هایی با کارکرد های یکسان اما خروجی های متفاوت دارند.
همه ی ابجکت ها متد هایی با کارکرد های یکسان اما خروجی های متفاوت دارند.

توی مثال بالا ما چندشکل مختلف از یک متد داریم و به این میگن polymorphism یا چند شکلی.


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


خب اینا چهار اصل یا ستون برنامه نویسی شی گرا بودن که بهشون پرداختیم اما ممکنه یه سری سوالا از جمله فرق اصل ABSTRACTION و ENCAPSULATION و یا فرق ABSTRACTION و INHERITANCE و... چیه و خب این قابل درکه چون همشون یه جورایی از کمک هم استفاده میکنن مثلا اصل POLYMORPHISM از اصل INHERITANCE استفاده میکنه تا پیاده بشه اینکه فرق اینا چیه هم ممکنه تو مصاحبه ها حتی پرسیده بشه و اما جواب اینه که مهم نیست که اینا شبیه هم هستن و یه سری چیزای مشترک دارند چیزی که اینارو از هم متمایز میکنه روشِ هر اصل هست که از اون یکی متفاوته:

  • روش encapsulation : جمع کردن دیتا های مرتبط داخلِ یک آبجکت برای غیر قابل دسترسی مستقیم کردنشون از محوطه ی بیرونی
  • روش abstraction: پنهان کردن اینکه متد چجوری کار میکنه و نمایش دادن اینکه متد چیکار میکنه در جهت کم کردن از پیچیدگی کدها
  • روش inheritance : به ارث بردن متد ها در جهت قابل اسفاده مجدد کردن آنها و جلوگیری دوباره نویسی و اشغال فضای اضافه
  • روش polymorphism: تغییر خروجی متدهای به ارث برده شده برای آبجکت های نمونه بدون نوشتن مجدد اون متد ها و بالا بردن قابلیت نگه داری و افزایش پرفورمنس


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

این مقاله اینجا به پایان میرسه و امیدوارم که برنامه نویسی شی گرا یا oop رو یک بار برای همیشه یاد گرفته باشید و تونسته باشم کمکی در جهت درک چگونگی این الگوی برنامه نویسی کرده باشم.


خدانگهدار و موفق باشید ?


javascriptpolymorphisminheritanceabstractionEncapsulation
درباره ی تکنولوژی های حوزه ی فرانت اند مینویسم.
شاید از این پست‌ها خوشتان بیاید