Yusefnejad

یوسف نژاد

Yusefnejad

یوسف نژاد


سال 1388 بود که با کتاب فوق العاده Framework Design Guidelines آشنا شدم. با اینکه جستجوی زیادی کردم نتونستم نسخه ای بهتر از یک pdf شامل اسکن صفحات این کتاب پیدا کنم (تمامی صفحات کتاب به صورت تصویر ذخیره شده بودن). اون موقع یه eBook Reader سونی مدل 900 داشتم که متاسفانه باهاش دستگاه نمیشد این pdf رو باز کرد، بنابراین مجبور شدم تا تمام صفحات کتاب رو پرینت بگیرم و از روی کاغذ A4 مطالعه کنم! کار ساده ای نبود، حجم کتاب هم زیاد بود، اما بالاخره تمومش کردم. 
در ضمن شرکت ما درحال تصمیم برای بازنویسی یک پروژه بزرگ بود. بنابراین پس از مطالعه این کتاب تصمیم گرفتم که بخشی از اون رو که مربوط به نامگذاری بود به صورت یک راهنما دربیارم تا تو این بازنویسی قواعد ثابتی برای پیاده سازی رعایت بشه.
پس از ترجمه و مرتب سازی مطالب و مشورت با همکاران و دوستان و اعمال بهبود های موردنیاز، متن نهایی این راهنما به صورت یک فایل Word آماده شد و پس از تایید مدیر پروژه به عنوان یک قانون لازم الاجرا در شرکت برای پیاده سازی پروژه ها درنظر گرفته شد.
در اون برهه یک آقایی به عنوان کارآموز وارد شرکت ما شد و یکی دو ماهی زیر نظر من کار کرد. بعدها که از شرکت رفت متوجه شدم که این راهنما رو با کمی تغییر با همون ادبیات و نگارش (که مخصوص خودم هست چون دستی هم در کار نویسندگی دارم) به اسم خودش و دقیقا با همون نام تو اینترنت منتشر کرده، بدون اینکه حتی اسمی از من یا شرکت برده باشه.
مدتها گذشت تا اینکه به عنوان یکی از نویسندگان سایت خوب NET Tips. این راهنما رو با کمی بهبود برای استفاده همه به صورت یک مطلب پست کردم که با استقبال خوبی هم روبرو شد.
حالا پس از چند سال که بالاخره موفق شدم وبلاگ خودم رو راه اندازی کنم، اون راهنما رو با بهبودهایی در اینجا ارائه میکنم.

پیشگفتار

نامگذاری ( Naming ) اجزای یک کتابخونه شاید در نگاه اول اهمیت چندانی نداشته باشه، اما تجربه نشون داده که نامگذاری صحیح و اصولی که از یکسری قواعد کلی و مناسب پیروی میکنه میتونه به مدیریت راحتتر برنامه، تغییر و توسعه احتمالی در آینده و مهمتر از همه به استفاده کنندگان از کتابخونه کمک بسیاری بکنه. این کار اجازه میده تا توسعه دهندگان زیادی در پروژه های مختلف بتونن براحتی از کتابخونه ما استفاده کنن.
نکته ای که باید بیشتر از همه به اون دقت کرد اینه که مهمتر از ثبات شکل و قاعده نامگذاری، نام اجزای یک کتابخونه باید طوری انتخاب بشن که اونا رو به آسانی قابل شناسایی بکنه و کارکردشون رو به روشنی نشان بده.
راهنمایی های ارائه شده در این مطلب بیشتر از اونکه منطقی فنی داشته باشن، قراردادهایی هستن که در اثر تجربه بدست اومدن. درضمن با اینکه استفاده از این راهنمایی ها میتونه در درازمدت تاثیر زیادی تو یکپارچگی و ثبات برنامه نویسی بزاره، اما در نظر داشته باشین که اعمال این قواعد تنها برای اجزای «قابل دسترس از بیرون» (غیر private) الزامی است!

نکته: گروهی که کتابخونه های پایه دات نت فریمورک (BCL یا Base Class Library) رو توسعه دادند به گفته خودشون زمان زیادی رو برای نامگذاری اجزای مختلف اختصاص دادن و نامگذاری رو به عنوان بخشی تعیین کننده در توسعه یک فریمورک میدونن.

نکته: قراردادهایی که در این سری مطالب ارائه میشه وحی منزل نیست که نشه تغییرش داد. اما این موضوع از اهمیتش کم نمیکنه و باعث نمیشه که اونو در حد یه پیشنهاد درنظر بگیرین. این رو هم مدنظر داشته باشین که استفاده از چندین قاعده متفاوت برای نامگذاری خیلی بدتر از استفاده نکردن از این قراردادهاست!

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

انواع نامگذاری

نامگذاری ها رو بر اساس ویژگی های مختلفی میشه طبقه بندی کرد. یکی از این ویژگی ها نحوه نگارش کلمات تشکیل دهنده یک نام، مخصوصا بزرگ یا کوچک بودن (Casing) حروف اولشونه. بر این اساس روشهای کلی زیر برای نامگذاری اجزای یک برنامه در دنیای امروز مرسومند:
1. Camel Casing: در این روش حرف اول در اولین واژه به صورت کوچک و حرف اول بقیه واژه ها به صورت بزرگ نوشته میشه. این روش به دلیل شباهتش با کوهانهای شتر به این نام معروف شده. مثل:
color,  firstName,  extendedSerializedQueryableObject, htmlTag

2. Pascal Casing: در این روش حرف اول همه واژه ها در نام شی به صورت بزرگ نوشته میشه. ازاونجاکه این روش در زبان برنامه نویسی Pascal زیاد استفاده میشد، به این نام معروف شده. مثل:
Color,  FirstName,  ExtendedSerializedQueryableObject, HtmlTag
به نحوه نگارش واژه html در این مثالها دقت کنین. بعدا در این باره بیشتر صحبت خواهد شد.

نکته: اختلاف نظرهایی بر سر انتخاب نام روش نامگذاری بین Pascal Casing و Camel Casing وجود داره. برای کسب اطلاعات بیشتر راجع به Casing و مباحث پیرامون اون میتونین به اینجا مراجعه کنین. 
مطلب دیگه ای هم راجع به نحوه انتخاب روش نامگذاری در تولید دات نت فریمورک از زبان Brad Abrams (از اعضای اصلی تیم طراحی دات نت فریمورک که در سال 2010 مایکروسافت رو ترک کرد) وجود داره که خوندن این مطلب خلاصه خالی از لطف نیست.

3. Hungarian: در این روش برای هر شی یک پیشوند با توجه به نوع اون در نظر گرفته میشه تا از روی نام شی بشه به نوعش پی برد. در ادامه و پس از این پیشوند سایر کلمات بر اساس روش Pascal Casing نوشته میشن. مثل:
clrColor,  strFirstName,  txtLastName,  btnSave
یکی از معایب این روش نامگذاری اینه که برنامه نویسا در طول توسعه، مدام نوع داده متغیرها رو عوض میکنن که در صورت استفاده از این روش، کار مدیریت و نگهداری کدهای برنامه به مرور مشکلتر میشه. همچنین درحالیکه انواع داده اولیه و رایج، شناسه های مشخصی دارن (مثل int و string و از این قبیل)، انواع داده ای که توسط خود برنامه نویسا تولید شدن این چنین نیستن و معمولا برنامه نویسا موفق نمیشن که شناسه ای مشخص و منحصر به فرد برای این نوع داده ها پیدا کنند.
با اینکه روش نامگذاری Hungarian مزایایی هم داره (مثل کمک به خوانایی کد به دلیل کمک به شناسایی راحتتر نوع داده)، معایب اون امروزه بیشتر به چشم میاد (مثل افزایش هزینه نگهداری، آشفتگی کدهای برنامه درصورت عدم مدیریت درست اون، و اینکه در نگاه برخی برنامه نویسا کدهای برنامه رو دچار پیچیدگی بیشتر و دسترسی کمتر میکنه).
البته در دنیای برنامه نویسی فانکشنال و پروسیجرال (مثل C) و برخی محیط های دیگه، ممکنه مزایای این روش ارزش بیشتری پیدا کنه، اما امروزه با وجود محیطهای برنامه نویسی شیءگرا (که طول عمر و محدوده قابل استفاده متغیرها رو بسیار کوچیک و قابل درک کرده و الگوهای پیاده سازی موجود طوری طراحی شدن که نوع دقیق داده رو کم اهمیت یا حتی بی اهمیت میکنه) این مزایا کمرنگترن.
همچنین در ابزارهای توسعه پیشرفته امروزی (مثل ویژوال استودیو) امکاناتی وجود داره که برنامه نویس رو براحتی از نوع داده اجزای برنامه باخبر میکنه (مثلا در VS فقط کافیه پوینتر ماوس روی جزء مورد نظر قرار بگیره تا اطلاعات موردنیاز نمایش داده بشه).

نکته: استفاده از این روش به جز در نام‌گذاری کنترل‌های UI (به دلیل کمکی که به شناسایی راحتتر این کنترلها در میان کدها میکنه) منسوخ شده.

4. Uppercase: در این روش همونطور که از نامش پیداست همه واژه ها با حروف بزرگ نوشته میشن. از این روش بیشتر در مواقعی که نام از حداکثر 2 واژه تشکیل شده استفاده میشه. مثل:
UI, IO
البته درباره نحوه استفاده درست از این روش در ادامه این مطلب بحث میشه. همچنین در برخی قراردادها، نامگذاری ثابت ها (Constantها) نیز از این روش پیروی میکنه.

قراردادهای کلی

1. نام اشیا نباید تنها در بزرگ یا کوچک بودن حروف با هم فرق داشته باشن. مثلا نباید دو کلاس با نام‌های MyClass و myClass تعریف کرد. درسته که برخی از زبون‌ها case-sensitive (حساس به حروف بزرگ و کوچک) هستن (مثل #C) اما بعضی ها هم نیستند (مثل VB.NET). پس اگه نیازه که اجزای یک کتابخونه در تمام محیط‌ها در دسترس باشن (که نیازه) باید از این قرارداد پیروی کنیم.

نکته: خود CLR کاملا حساس به حروف بزرگ و کوچک (case-sensitive) هست. در زبونهایی که این ویژگی رو ندارن (مثل VB.NET) وظیفه برقراری ارتباط با متدهای کتابخونه های case-sensitive (مثلا نوشته شده با #C) و حل این مشکل به عهده کامپایلر اون زبون هست. یعنی در زمان کامپایل و تولید کدهای IL، این کامپایلر هست که فرمت و نگارش درست API موردنظر رو فهمیده و اون رو با فرمت درست در متادیتای برنامه قرار میده. در این فرایند خود CLR نه چیزی میدونه و نه کاری انجام میده.
در زمان استفاده از reflection (مثلا فراخوانی یک متد)، APIهای خود ریفلکشن هستن که درصورت نیاز عملیات case-insensitive رو هم پشتیبانی میکنن تا در زبونهایی این چنینی مشکلی از این بابت پیش نیاد. پس باز هم در نهایت خود CLR چیزی از این عملیات نمیدونه و همچنان case-sensitive رفتار میکنه.

2. نباید از underscore برای جداسازی کلمات یک نام استفاده بشه. یعنی first_number اشتباهه و firstNumber درسته.

3. به عنوان یک اصل کلی تا اونجا که امکان داره نباید از کاراکترهایی به غیر از حروف الفبا برای نامگذاری استفاده کرد.

4. از به‌کار بردن مخفف کلمات در نام‌گذاری اشیا باید دوری بشه. مثلا به جای استفاده از GetChr باید از GetCharacter استفاده کرد.
البته در برخی موارد که مخفف واژه موردنظر کاربرد گسترده ای داره میشه از عبارت مخففش هم استفاده کرد. مثل UI به جای UserInterface و یا IO به جای InputOutput که نحوه نامگذاری متفاوتی هم خواهد داشت. این مورد در ادامه این سری بیشتر بحث میشه.

5. باید از کلماتی که خوانایی آسونتری دارن استفاده کرد. مثلا VerticalAlignment در زبان انگلیسی راحتتر از AlignmentVertical خونده میشه.

6. باید خوانایی رو بر کوتاهی ترجیح داد. مثلا عبارت CanScrollHorizontally خواناتر از ScrollableX هست و بنابراین درستتر.

7. نباید از کلمات کلیدی زبانهای برنامه نویسی رایج استفاده کرد. با اینکه زبان های منطبق بر CLS همگی مکانیزمی برای استفاده از کلمات کلیدی به عنوان نام اشیای برنامه دارند (مثلا در #C با استفاده از کاراکتر @)، ولی به عنوان یک اصلی کلی باید از استفاده از این ویژگی پرهیز کرد.


.: در قسمت بعد درباره جزئیات نامگذاری بحث میشه.
:.
  • یوسف نژاد

NET Framework.

NET.

نامگذاری

Naming

نظرات  (۱)

بخش‌هایی از این نظر که با * مشخص شده، توسط مدیر سایت حذف شده است
سلام 
راه اندازی وبلاکتون رو تبریک میگم. مطمئن هستم با توجه به دانش و تلاش شما هر روز مطالب سایت شما غنی تر خواهد شد.
*** *** ***** ** **** ***** *** ** **** *** *** **** * ** *** ***** ***** **** ******** * ** ***** **** ** ***** *** ** ***** ******
منتظر ادامه و تکمیل این موضوع (اصول و قراردادهای نامگذاری) هستم.
پاسخ:
سپاس.

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی
آخرین نظرات