۱۰ نکته برای نوشتن کد بهتر و سادهتر – یک راهنمای جامع در خصوص کدنویسی مرتب
بیشک برنامهنویسی کاری دشوار است. باید زبانهای مختلف را بیاموزید و الگوریتمها را مطالعه نمایید؛ اما این که سعی کنید کدهای یک برنامه پیچیده را طوری بنویسید که هنگام مطالعه، شخص را به زحمت نیندازد، امری جداگانه است.
نوشتن کد تمیز و مرتب چیزی است مانند طراحی، آشپزی یا عکاسی. گرچه در نگاه اول ممکن است ساده به نظر بیاید؛ اما به هیچ وجه ساده نیست. شاید از خود بپرسید، اصلاً چرا باید خود را اذیت کنیم؟ دلیل ارزشمند بودن تلاش برای کدنویسی مرتب موارد زیر هستند:
- حل مشکلات آسانتر میشود. زمانی که به کدهای مرتب نگاه میکنید، روش حل مسئله شما نیز تغییر مییابد. به جای این که کورکورانه به دنبال راهحل باشید، الگوریتمها و طراحی نرمافزار ظریفتر و آگاهانهتر میشود.
- زمان کمتری صرف نگهداری کد میشود. کد مرتب، خوانایی و ادراک آسانتری دارد. از این رو زمان کمتری صرف درک بخشهای مختلف کد میشود و این زمان میتواند صرف اصلاح، بازبینی و گسترش کد شود.
- ایدهها به راحتی انتقال مییابند. اگر مشغول همکاری با برنامهنویسهای دیگر باشید، کدنویسی مرتب باعث میشود که احتمال سوءبرداشت بین شما و دیگران کاهش یابد و در بلندمدت تعداد باگها را کاهش میدهد.
در ادامه برخی گامهای آغاز کدنویسی مرتب را معرفی کردهایم:
1. استفاده از نامهای گویا
متغیرها، کلاسها و تابعها چه هستند؟ روشهای زیادی برای پاسخ به این سؤال وجود دارد؛ اما وقتی عمیقتر فکر کنید، اینها چیزی به جز رابط بین یک برنامهنویس و منطق نهان برنامه نیستند.
بنابراین وقتی از نامهای غیر مشخص و غیر توصیفی برای متغیرها، کلاسها و توابع استفاده میکنید، در واقع منطق برنامه را در چشم هر برنامهنویسی که کد را میخواند، مبهمتر میسازید. این برنامهنویس حتی ممکن است خود شما باشید.
من یک برنامهنویس عالی نیستم؛ من تنها یک برنامهنویس خوب با عادتهای عالی هستم.
- Kent Beck
متغیری به نام dxy به چه معنی میتواند باشد؟ هیچ کس نمیداند. احتمالاً باید کل آن قطعه کد را بخوانید و با استفاده از مهندسی معکوس، معنای آن را کشف کنید. از سوی دیگر معنی متغیری به نام distancebetweenXY تقریباً بلادرنگ قبل تشخیص است.
همین نکته در مورد نام کلاسها و توابع نیز صدق میکند. سعی کنید از مواردی مانند ()CalcTan کمتر استفاده کنید و به جای آن از ()CalculateTangent و یا ()CalcTangentAngle استفاده نمایید.
2. هر کلاس/تابع باید یک هدف خاص داشته باشد
آیا تاکنون با تابعی مواجه شدهاید که در صدها یا حتی هزاران خط نوشته شده باشد؟ اگر چنین بوده است، در این صورت احتمالاً میدانید که گشتن درون چنین تابعی و درک و ویرایش آن تا چه حد رنجآور است. توضیحات درون تابع میتوانند کمک کنند؛ اما این کمک کاملاً محدود است.
برنامهنویسی عبارت است از تجزیه یک کار ناشدنی به چند کار ممکن کوچکتر.
- Jazzwant
کد مرتب را میتوان به قطعه کدهای منفرد تقسیم کرد. هر تابع باید با هدف انجام یک کار منفرد و هر کلاس با هدف نمایش یک مفهوم خاص نوشته شود. این همان سادهسازی امور است و هر جا که تردید داشتید، بدانید که کد شما هر چه سادهتر باشد، مرتبتر است.
در عمل یک محاسبه پیچیده مانند GetCreditScore() (یعنی محاسبه رتبه اعتباری) را میتوان به چند تابع کمکی (helper) مانند ()GetCreditReports (دریافت گزارشهای اعتبار)، ()ApplyCreditHistoryAge (بهکارگیری سابقه اعتباری) و ()FilterOutstandingMarks (حذف نشانگرهای پراکنده) تقسیم نمود.
3. حذف کدهای غیرضروری
استفاده از کدهای غیرضروری عادت بدی است که برخی از برنامهنویسان نمیتوانند رهایش کنند. برای توضیح بیشتر به این سناریو توجه کنید: فرض کنید میخواهید یک قطعه کد را بهینهسازی کنید، بنابراین آن را کامنت میکنید و درست زیر همان کد نسخه بهینه را بازنویسی میکنید و با این که کد جدید کار میکند؛ کد قدیمی را نیز نگه میدارید، چون ممکن است یک جایی به کار بیاید یا در مواقع بروز خطا بتوانید دوباره به کد قبلی بازگردید.
منظور از این که نرمافزار شبیه هیچ چیز دیگر نیست، این است که هر برنامهای به منظور دور انداخته شدن خلق میشود. نکته اصلی این عبارت آن است که نرمافزار همواره باید به صورت یک حباب با عمر کوتاه نگریسته شود.
- Alan J. Perlis
چنین برنامهنویسهایی در طی زمان با مقادیر بالایی از کدهای کامنت شده مواجه میشوند که نیازی به آنها ندارند، و صرفاً باعث شلوغی و سردرگمی در کد میشود. نکته جالب اینجاست که در اغلب موارد کدهای اصلاح شده آن قدر تکامل پیدا میکنند که کد کامنت شدهی اولیه، اصلاً امکان بازیابی هم نخواهد داشت.
نکته اینجاست که این کدهای پشتیبان کامنت شده با استفاده از نرمافزارهای کنترل سورس منسوخ میشوند. اگر هنوز از چیزی مانند گیت (Git) یا Mercurial استفاده نمیکنید، همین امروز باید شروع به استفاده از یک نرمافزار کنترل سورس بکنید. بدین ترتیب میتوانید کدهای مرتبتری بنویسید.
4. خوانایی > هوشمندی
بسیاری از برنامهنویسها «کد مرتب» را با «کد هوشمند» اشتباه میگیرند، به طوری که فکر میکنند تبدیل کردن ده خط کد به یک خط باعث مرتبتر شدن آن میشود. مسلم است که چنین کدی فضای کمتری در صفحه اشغال میکند؛ اما آیا درک آن نیز آسانتر میشود؟ گاهی اوقات ممکن است چنین باشد؛ اما در اغلب موارد چنین حالتی وجود ندارد.
همه میدانند که دیباگ کردن، دو برابر دشوارتر از نوشتن کد در وهله اول است. بنابراین اگر در زمان نوشتن کد هر چقدر بتوانید هوشمندانه عمل کنید، چگونه خواهید توانست کد خود را دیباگ کنید؟
- Brian W. Kernighan
اغلب برنامهنویسها کد هوشمند را دوست دارند، زیرا حسی شبیه حل یک معما دارد. آنها روش منحصر به فرد و خاصی برای پیادهسازی یک کار خاص پیدا میکنند که میتوان آن را یک «میانبر» نامید و به آن به عنوان یک مقیاس برای اعتبارسنجی مهارتهای برنامهنویسی نگاه میکنند.
اما برای نوشتن کد مرتب، میبایست این نوع غرورها را پشت در جا بگذارید. همواره سعی کنید کد خود را طوری بنویسید که همه چیز برای فرد بعدی که آن را میخواند بهینه باشد، زیرا همیشه این احتمال هست که این برنامهنویس بعدی به شما مراجعه کند و هیچ چیزی شرمآورتر از این نیست که خودتان نتوانید کد هوشمندانهای که نوشتهاید را بخوانید یا درک کنید.
5. از سبک کدنویسی یکنواختی استفاده کنید
در مورد رویههای برنامهنویسی صحیح، بسیار گفته شده است؛ اما یکی از معایب آن این است که افراد مبتدی طیف گستردهای از عادتهای بعضاً متناقض مییابند که به طور خاص برای حفظ سبک کدنویسی به کار میگیرند.
در این نوشته قصد نداریم بیان کنیم که کدام سبک کدنویسی بهتر از دیگری است. شما میتوانید هر نوع سبکی که دوست دارید را ادامه دهید. اگر ترجیح میدهید قبل از فراخوانیهای متد اسپیس بزنید مشکلی نیست. اما اگر Tab را به اسپیس ترجیح میدهید، نباید اجازه دهید دیگران شما را برخلاف آن متقاعد کنند.
هر کاری که میکنید بکنید؛ اما رویه یکنواختی داشته باشید.
زیبا بهتر از زشت است
صریح بهتر از ضمنی است.
ساده بهتر از پیچیده است
پیچیده بهتر از درهم است.
مسطح بهتر از تودرتو است
پراکنده بهتر از فشرده است
خوانایی مهم است
- تیم پترز، کتاب ذن در پایتون
اگر میخواهید از camelCaseNaming (نامگذاری شتری: در این روش اسامی مختلف به صوت چسبیده به هم نوشته میشوند و حرف ابتدای هر کلمه به صورت بزرگ استفاده میشود) برای متغیرها استفاده کنید، آن را با underscore_naming (نامگذاری با استفاده از زیرخط: در این روش کلمات مختلف با علامت _ از هم جدا میشوند.) مخلوط نکنید. اگر در یک جا از ()GetThisObject استفاده میکنید، در جای دیگر از ()FetchThatObject استفاده نکنید. همچنین تلاش کنید هرگز اسپیس و Tab را با هم مخلوط نکنید، چون در این صورت شایسته است که شما را از استفاده از کیبورد محروم کنند.
در مورد کاری که میخواهید انجام دهید از ابتداییترین مراحل تصمیمگیری کنید و گام به گام حرکت کنید. برخی زبانها مانند پایتون و #C راهنماهای سبک کدنویسی خاصی در سطح زبان دارند که بهتر است از آنها پیروی کنید.
6. معماری صحیح را انتخاب کنید
پارادایمها و معماریهای مختلفی وجود دارند که میتوانید برای ایجاد پروژههای خود از آن استفاده کنید. توجه کنید که چگونه میتوانید یک معماری مناسب خود و نه لزوماً بهترین نوع موجود را انتخاب کنید، چون در این خصوص بهترین نوع وجود ندارد.
برنامهنویسی بدون قواعد الزامی و سبک طراحی، هنر افزودن باگ به یک فایل متنی خالی است.
- Louis Srygley
برای نمونه، الگوی مدل-چشمانداز-کنترلر (MVC) اینک در توسعه وب بسیار متداول است، زیرا به سازمانیافتگی کد کمک میکند و تلاشهای نگهداری کد را به کمترین مقدار میرساند.
به طور مشابه الگوی نهاد-مولفه-سیستم (ECS) نیز در توسعه بازی هم اینک بسیار رایج است، زیرا به ماژول سازی دادهها و منطق بازی به طریقی که نگهداری آن آسانتر باشد کمک میکند و کدی که بدین نحو تولید میشود، خوانایی بالاتری دارد.
7. یادگیری اصطلاحهای خاص هر زبان
یکی از دشواریهای کسب مهارت در یک زبان برنامهنویسی جدید، یادگیری تفاوتهای ظریفی است که آن را از دیگر زبانها متمایز میسازد. این تفاوتها میتوانند اختلاف بین کد زشت و درهم پیچیده با کد زیبا و با نگهداری آسان باشند.
برای مثال پایتون، جاوا و جاوا اسکریپت را در نظر بگیرید. همه این زبانها از همدیگر متفاوت هستند تا حدی که بسته به این که از چه زبانی استفاده میکنید، روش اندیشیدن شما نیز متفاوت خواهد بود.
زبانی که روش اندیشیدن شما در مورد برنامهنویسی را تغییر ندهد، ارزش یادگیری را ندارد.
- Alan J. Perlis
گرچه پایتون به طور کامل از روش کدنویسی فشرده و تایپ دهی اردکی (Duck Typing) بهره میگیرد؛ اما جاوا بیشتر از توضیحات طولانی و عبارتهای صریح استفاده میکند. هر زبانی اصطلاحهایی دارد (مانند list comprehensions در پایتون) که روش خاصی از کدنویسی را تشویق میکند. بهتر است این موارد را نیز بیاموزید.
همچنین ضد الگوهایی نیز وجود دارند که باید از آنها پرهیز کنید. این موارد در واقع الگوهای طراحی غیر بهینه هستند که موجب تولید کدهای ناکارآمد، غیر قابل اعتماد و یا بد میشود. سعی کنید همه ضد الگوهای مرتبط با زبان انتخابی خودتان را مطالعه کرده و از یادگیری آنها خودداری کنید.
8. کد اساتید برنامهنویسی را مطالعه کنید
اگر میخواهید کد مرتب بنویسید، بهترین کار آن است که با روش کدنویسی مرتب اساتید این حوزه آشنا شوید تا چرایی این روش کدنویسی را درک کنید. برای انجام این کار روشی بهتر از مطالعه فایلهای سورس استادان هر زبان وجود ندارد.
بدیهی است که نمیتوانید به شرکت مایکروسافت وارد شده و به پروژههای آنها نگاه کنید؛ اما میتوانید همواره بهترین پروژههای متن-باز را جستجو کنید. اگر نمیدانید از کجا شروع کنید، میتوانید به گیتهاب مراجعه کنید و برخی از سورس های مشهور که در زبان انتخابی شما نوشته شدهاند را مطالعه نمایید.
هر احمقی میتواند کدی بنویسد که رایانه درک کند. برنامهنویسان خوب کدی مینویسند که انسانها درک کنند.
- مارتین فاولر، بازنویسی: بهبود طراحی کد موجود
در نهایت یکی از دلایل وجود پروژههای متن-باز همین است که افراد مختلف بتوانند از آن چیزهایی بیاموزند. اگر قصد داشته باشید تا در چنین پروژهای مشارکت کنید، این امر موجب تسریع فرایند یادگیری شما میشود.
اکثر برنامهنویسان مبتدی بدین ترتیب با شیوه صحیح کدنویسی آشنا میشوند. در مواردی برخی از برنامهنویسان تازهکار حتی ممکن است از مشاهده سبک برنامهنویسی متفاوت این پروژههای بزرگ ناامید شوند؛ اما در نهایت با پشتکار فراوان میتوانند چیزهای زیادی از پروژههای اوپنسورس بیاموزند.
9. نوشتن توضیحات خوب
نوشتن توضیحات مناسب، قدیمیترین توصیه در دنیای برنامهنویسی است. در واقع به محض این که مفهوم درج توضیح برای کد به برنامهنویسان مبتدی آموزش داده میشود، آنها کاملاً تشویق میشوند تا جایی که میتوانند از توضیحات بیشتری در کد خود استفاده نمایند.
اما در مواردی نیز این تأکید زیاد، اثر معکوسی دارد. برخی برنامهنویسهای تازهکار به طور خاص گرایش به توضیح بسیار در مورد مسائلی دارند که نیازی به توضیح ندارند و معنی یک توضیح خوب را به درستی متوجه نشدهاند.
همواره طوری کد بزنید که گویا فردی که میخواهد کد شما را بازبینی کند، یک بیمار خطرناک روانی است که محل زندگی شما را میشناسد.
- John Woods
قاعده سرراست برای یک توضیح مناسب چنین است: دلیل وجودی توضیحات این است که بیان کند چرا یک کد نوشته شده است و نه این که چه کاری انجام میدهد. اگر کد به قدر کافی مرتب نوشته شده باشد، به اندازهای خود توصیف خواهد بود که بتوان حس زد چه کاری انجام میدهد. توضیح برای این درون کد درج میشود که نیت ناپیدای چرایی نگارش کد را بیان کند.
استفاده از توضیحات برای هشدار نیز مناسب است (مثلاً «حذف این کد باعث میشود بخشهای الف، ب و ج از کار بیفتند»؛ اما وظیفه اصلی آن مشخص ساختن چیزهایی است که به تنهایی از مطالعهی گذرای کد نمیتوان درک کرد (برای مثال «از این پارامتر استفاده کنید چون ...»).
10. بازسازی، بازسازی، بازسازی
بازسازی کد (Refactor) همانند ویرایش، بخشی از فرایند نوشتن کد است. بیزاری برخی افراد از بازسازی کد در نهایت خیلی زود منجر به تولید کدی میشود که غیر قابل نگهداری است، بنابراین از هر جنبه که نگاه کنید، بازسازی یکی از مهمترین جنبههای کدنویسی است.
به طور خلاصه بازسازی کد تنها یک اصطلاح جذاب در مورد پاکسازی کد بدون تأثیر بر رفتار واقعی آن است.
هر زمان که مجبور هستم بیندیشم یک کد چه کاری انجام میدهد، از خود میپرسم آیا میتوانم کد را بازسازی کنم تا فرایند این ادراک سریعتر صورت بگیرد.
- مارتین فاولر، بازسازی: بهبود طراحی کد موجود
یکی از بهترین توصیههایی که میتوان کرد این است که «برای کد بد توضیح ننویسید؛ بلکه آن را بازسازی کنید.» همان طور که فاولر در نقل قول فوق توضیح داده است، اگر کدی به آن حد پیچیده بود که حس کردید به توضیح نیاز دارد، شاید در واقع بهتر باشد که آن را بازسازی کنید.
به علاوه همچنان که بخشهای مختلف کد را ویرایش میکنید، به طور مداوم تلاش کنید کدی که پس از بازبینی بر جای میماند بهتر از کدی باشد که در ابتدا با آن مواجه شدید. شاید این کار نیازمند ایجاد تفاوتهای خیلی ظریفی باشد؛ اما در بلندمدت نتایج بسیار شگرفی ایجاد میکند و حتی میتواند از فرسودگی ذهنی نیز جلوگیری کند.
همواره چیز جدیدی برای آموختن وجود دارد
برنامهنویسی که به خوبی آموخته است چگونه کد مرتب بنویسد، بسیار شبیه نوآموزی است که در حال یادگیری نگارش صحیح است. یگانه روش مشخصی برای انجام صحیح این کار وجود ندارد؛ اما بسیاری راههای نادرست وجود دارد که شاید سالها طول بکشید تا فرد در این مسیر مهارت کسب کند.
برخی افراد مهارتهای مورد نیاز برای کدنویسی خوب را ندارند و در نهایت برنامهنویسی را ترک میکنند. اشکالی در این قضیه وجود ندارد، زیرا بسیاری از شغلهای دیگر در حوزه فناوری وجود دارند که نیازی به کدنویسی ندارند.
اما برای افرادی که میخواهند مسیر برنامهنویسی را ادامه دهند، کدنویسی مرتب چیزی است که میبایست نهایت تلاش خود را برای آن بکنند، هر چند که این تلاش به مدت همه عمرشان تداوم داشته باشد.
اگر این نوشته مورد توجه قرار گرفته است، پیشنهاد میکنیم موارد زیر را نیز مطالعه نمایید:
- ۱۰ اشتباه رایج در کدنویسی و روشهای اجتناب از آنها
- مجموعه آموزشهای برنامهنویسی
- عجیبترین اصول برنامهنویسی که نمیدانستید
- آموزش اصول و مبانی برنامه نویسی
- مجموعه آموزش های پروژه محور برنامه نویسی
==