برنامه نویسی پر است از قوانین نوشته و نانوشته ای که بسیاری از برنامه نویسان حرفهای سراسر دنیا از آنها تبعیت می کنند. وقتی که ما شروع به یادگیری یک زبان برنامه نویسی می کنیم، پیش از هر چیز با قوانین خاص آن زبان آشنا میشویم و یاد میگیریم که با آن زبان خاص چه کارهایی را میشود انجام داد و چه کارهایی را نمی توان!
توجه داشته باشیم که یادگیری قوانین مختص هر زبان در مقایسه با سایر قوانین حاکم بر زبانهای برنامه نویسی و اصول توسعه ی نرمافزار بسیار آسان است چرا که در صورت عدم تبعیت از این قوانین -مثلا قرار دادن عدد در ابتدای نام متغیر در یک زبان برنامه نویسی که برای نامگذاری متغیرها اجازه نداریم از عدد به عنوان کاراکتر اول استفاده کنیم- منجر به Crash (کرش یا منهدم شدن) برنامه می شود.
اما در برنامه نویسی شیء گرایی همه چیز به همین شفافی نیست. به طور مثال، اگر در برنامهای که با یک زبان شیء گرا نوشته شده ما اقدام به ایجاد چندین کلاس متفاوت کنیم که چیزی در حدود 90 درصد آنها کار مشابهی را انجام می دهند، ما با هیچ مشکلی مواجه نخواهیم شد اگرچه که این کار بر خلاف اصول برنامه نویسی شیء گرایی است.
برای این منظور، یکسری Guidelines یا «راه کارهایی» برای استفاده ی اصولی از مفاهیم برنامه نویسی شیء گرایی وجود دارد که با پیروی از آن ها، این تضمین را میتوانیم ایجاد کنیم که برنامه هایمان ساختار یافته، اصولی، قابل دیباگ کردن، قابل توسعه و از همه مهمتر حرفهای هستند.
توجه داشته باشیم راه کارهایی که در آموزشهای بعد ارائه خواهند شد هیچ ربطی با دیزاین پترن ها ندارد. در واقع، دیزان پترن ها راه کارهایی برای یک موقعیت خاص در برنامه نویسی شیء گرایی هستند اما راه کارهای مد نظر ما چیزهایی کلی هستند و یک دید همه جانبه در ارتباط با برنامه نویسی شیء گرایی به ما خواهند داد.
برای مثال، قانون DRY را میتوان در نظر گرفت که مخفف واژگان Don`t Repeat Yourself به معنی «هرگز کار تکراری نکنید!» است. اگر در کدنویسی مواقعی برای ما پیش میآید که قطعه کدی را از جایی در سورس کد کپی کرده سپس در جای دیگر دقیقاً همان قطعه کد را پیست می کنیم، بر اساس قانون DRY این کار کاملاً اشتباه است. در چنین مواقعی ما به سادگی میتوانیم کدهای این چنین را در قالب متدهای مختلفی ایجاد کرده و هر کجا که به آن کد نیاز داشتیم، متد مد نظر را Call یا «فراخوانی» کنیم. علاوه بر این، اگر در آینده بخواهیم در قطعه کد خاصی تغییری ایجاد کنیم، صرفاً نیاز خواهیم داشت تا این تغییر را در یک جا اعمال کرده که در نتیجه تغییر مد نظر ما در هر کجایی که آن متد را فراخوانی کرده باشیم اعمال خواهد شد.
به عنوان مثالی دیگر، قانون YAGNI که مخفف واژگان You Ain`t Gonna Need It به معنی «بعید به نظر می رسه که در آینده بهش نیاز داشته باشی!» است. برای برنامه نویسان -به خصوص برای برنامه نویسان مبتدی- بسیار پیش میآید که دوست دارند برنامههایی که مینویسند کامل و جامع باشند و جالب است بدانیم که در برخی مواقع برنامه نویسان دچار وسواس فکری میشوند به این شکل که میخواهند در برنامه ی مد نظرشان تمامی ایدههایی که دارند اعمال شوند. راحت بگوییم که این سیاست در توسعه ی نرمافزار کاری بس اشتباه است! اگر شما با خود فکر میکنید که مثلاً فلان قابلیت در آینده ممکن است به کار آید، می بایست دست نگه دارید. صرفاً روی قابلیتهای کلیدی نرمافزار تمرکز کنید و در صورتی که در آینده نیاز به قابلیت جدیدی داشتید، در زمان مناسب آن قابلیت را خواهید افزود.
گاهی اوقات، سورس کدی که نوشتهایم به درستی کار میکند اما یک جای کار می لنگد که گویی همه چیز به درستی در جای خودش قرار نگرفته است. به طور مثال، متدهای طولانی را میتوان در نظر گرفت. گفته میشود یک متد خوب متدی است که از آغاز تا پایان آن بدون اسکرول کردن سورس کد در صفحه نمایش قابل روئیت باشد. شاید چنین چیزی کمی اغراق آمیز باشد و نتوان متدهایی که کارهای خاصی انجام میدهند را به این کوتاهی نوشت اما در اینجا منظور اصلی این است که تا حد ممکن می بایست از نوشتن متدهای طولانی خودداری کرده و متدهای طولانی را به چندین متد کوچک تقسیم بندی کنیم که در این صورت خوانایی سورس کد از یک سو و همچنین دیباگ کردن برنامه در صورت نیاز از سوی دیگر به مراتب راحتتر صورت خواهد گرفت.
به عنوان مثالی دیگر، میتوان به نامگذاری های خیلی کوتاه و یا خیلی بلند اشاره کرد. تحت هیچ عنوان متغیری را تحت عنوان مثلاً i نامگذاری نکنید چرا که در مرور سورس کد در آینده توسط خودمان و یا سایر توسعه دهندگان دچار سردرگمی خواهیم شد. نام های بسیار طولانی نیز مشکل زا هستند. به طور مثال نامی همچون noOfStudentsInEachClassOfUniversity به معنی «تعداد دانشجویان در هر کلاس دانشگاه» را میتوان خیلی سادهتر و به صورت studentsNo به معنی «تعداد دانشجویان» نوشت.
مسأله ی دیگری که می بایست به آن اشاره کرد، Comment گذاری است. به طور کلی، کامنت ها توضیحاتی هستند که از دید کامپایلرها، مفسرها و همچنین کاربران نرمافزار پنهان بوده و صرفاً در معرض دید توسعه دهنده ی نرمافزار قرار میگیرند تا با ماهیت بخشهای مختلف نرمافزار آشنا شده و بداند که هر بخش چه کاری انجام می دهد. گفته میشود کد خوب کدی است که آنقدر تمیز نوشته شده باشد و همه چیز آن شفاف باشد که نیازی به کامنت نداشته باشد و خود کد گویای عملکردش باشد اما به هر حال امروزه کامنت گذاری در سورس کد به عنوان یک Best Practice در آمد و لاجرم ما هم می بایست از این قانون تبعیت کنیم. گاهی اوقات برنامه نویسان مبتدی را میبینیم که دچار وسواس کامنت نویسی میشوند به طوری که تعداد کامنت های ایشان در سورس کد به مراتب بیشتر از کدهای اصلی برنامه است:
// This creates a variable called box & sets it to zero
int box = 0;
همانطور که در مثال فوق می بینیم، ما یک متغیر ایجاد کردهایم تحت عنوان box به معنی «بسته» اما کامنتی که برای آن با مضمون «این متغیری است تحت عنوان جعبه که دارای مقدار اولیه ی صفر است» در نظر گرفتهایم که در حقیقت نوشتن این کامنت اصلاً ضرورتی ندارد و صرفا منجر به شلوغ شدن سورس کد می شود. در ضمن، اگر کامنت هایی در سورس کد خود بنویسیم که به معنای واقعی کلمه ارزشمند نباشند، وقتی در آینده توسعه دهنده ی دیگری به سورس کد ما نگاه کند، با توجه به این که کامنت ها در برخی جاهای برنامه واقعا غیرضروری و اضافی هستند، این ایماژ برایش ایجاد می شود که گویی تمامی کامنت های نوشته شده به این شکل هستند و این احتمال نیز وجود دارد که دیگر به هیچ وجه به کامنت ها -حتی آن هایی که به خوبی و درستی نوشته شده اند- توجهی نکند!
به عنوان مثال آخر، میتوان کلاسهایی را مثال زد که به قول معروف «همه فن حریف» هستند. این کلاسها آنقدر قابلیت و عملکرد برایشان در نظر گرفته شده که در جای جای سورس کد، رد و نشانی از آنها می یابیم که اتخاذ چنین سیاستی نیز اشتباه است. در واقع، هر کلاس در برنامه نویسی شیء گرایی قرار است یک کار خاص را انجام دهد. پس چنین کلاسهایی را می بایست به چندین کلاس تخصصی و مجزا از یکدیگر با یکسری متدهای کاربردی برای هر کدام بازنویسی کرده و هر کجا که نیاز بودم، از آنها استفاده نماییم.
آنچه در بالا بدان اشاره شد، صرفاً Guideline هایی بودند که هم در برنامه نویسی سنتی و هم در برنامه نویسی شیء گرایی می بایست مد نظر داشت اما همانطور که قبلاً هم گفتیم، در OOP نیاز به یکسری قوانین سخت گیرانه تری داریم تا این تضمین ایجاد شود که ما به درستی اصول شیء گرایی را به کار گرفتهایم که در آموزشهای بعد با این قوانین بیشتر آشنا خواهیم شد.