PDA

View Full Version : استانداردهای کد نویسی



amir_saniyan
سه شنبه 20 فروردین 1387, 21:52 عصر
سلام

کسی مطالب آماده در مورد استانداردهای کدنویسی برای زبان C++ (به فارسی) داره؟
سپاس

amir_saniyan
سه شنبه 20 فروردین 1387, 21:57 عصر
باز هم سلام.

خودم یک چیزهایی آماده کردم اما می‌خواهم کامل‌ترش کنم (برای پروژه کتابخانه هوش‌مصنوعی: http://www.ailibrary.net)

به نام پروردگار


رهنمودهای طراحی


رهنمودهای نامگذاری:

نامگذاری شناسه‌ها شامل نامگذاری فضاهای نام، رده‌ها، ساختارها، انواع داده‌ای، داده‌های شمارشی، اعضای یک ساختار یا رده، متدها و پارامترها می‌شود.
روش‌های نامگذاری:

روش‌های نامگذاری عبارتند از:

روش نامگذاری پاسکال: اولین حرف شناسه و اولین حرف هر کلمه در شناسه با حروف بزرگ نوشته می‌شود و بقیه حروف شناسه با حروف کوچک نوشته می‌شوند. مثل BackColor.
روش نامگذاری شتری: اولین حرف شناسه کوچک و اولین حرف هر کلمه در شناسه با حروف بزرگ نوشته می‌شود و بقیه حروف شناسه با حروف کوچک نوشته می‌شوند. مثل backColor.
روش نامگذاری زیر خط دار: تمامی حروف شناسه با حروف کوچک نوشته می‌شوند و بین هر کلمه در شناسه از زیر خط استفاده می‌گردد. مثل back_color
روش نامگذاری حروف بزرگ: تمامی حروف شناسه با حروف بزرگ نوشته می‌شوند و بین هر کلمه در شناسه از زیر خط استفاده می‌گردد. مثل IO.قواعد حروف بزرگ و کوچک در نامگذاری شناسه‌ها:

تمامی شناسه‌ها به جز ثوابت از روش نامگذاری زیر خط دار استفاده نمایند.نام توابع، فضاهای نام، رده‌ها، ساختارها، متدها، و انواع داده‌های شمارشی باید از قانون بالا پیروی نماید.

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

تمامی ثوابت و ماکروها از روش نامگذاری حروف بزرگ استفاده نمایند.نام ثوابت، اعضای داده‌های شمارشی و ماکروها باید از قانون بالا پیروی نماید.
قواعد عمومی در نامگذاری شناسه‌ها:

اسامی شناسه‌ها طوری انتخاب گردد که با معنی بوده و به سادگی قابل خواندن باشند. به عنوان مثال horizontal_alignment نسبت به alignment_horizontal ساده‌تر و قابل فهم‌تر می‌باشد.
اسامی با معنی‌تر را بر اسامی کوتاه‌تر ترجیح دهید. به عنوان مثال can_scroll_horizontally بهتر از scrollable_x می‌باشد (چون جهت محور Xها مبهم می‌باشد).
از نمادهای مجارستانی برای نامگذاری استفاده ننمایید.در روش نمادهای مجارستانی، به ابتدای نام شناسه اختصاری که نشان‌دهنده نوع شناسه است نیز اضافه می‌گردد. مثل CWnd که حرف C در ابتدای نام شناسه نماد رده می‌باشد.

از اختصار کلمات در نام شناسه‌ها بپرهیزید. به عنوان مثال به جای btn از button استفاده ننمایید.
تنها در مواردی از مخفف کلمات استفاده نمایید که مخفف کلمه به اندازه کافی شناخته شده باشد. به عنوان مثال html مخففی شناخته شده می‌باشد.
تا حد امکان در انتخاب اسامی تکیه بر معنی باشد. به عنوان مثال get_length از get_int با معنی‌تر است.
از اسامی معمول‌تر مثل value و item به جای تکرار نام نوع استفاده نمایید.نامگذاری کتابخانه‌ها:

نام طرح‌ها و همچنین نام پرونده اجرایی طرح‌ها همنام باشد. به عنوان مثال نام طرح image_processing و نام پرونده image_processing.dll باشد. همچنین در نام طرح‌ها و پرونده‌ها به طور کلی نیازی به تکرار نام رهیافت (به عنوان مثال ailibrary نمی‌باشد.)نامگذاری پرونده‌ها:

پسوند پرونده‌های سرآیند C++ حرف h (کوچک) و پسوند پرونده‌های کد حروف کوچک cpp باشد.
نام هر پرونده با نام نوع داخل آن یکسان باشد. به عنوان مثال نام پرونده سرآیند و کد یک رده با نام خود رده باید یکی باشد.قواعد نامگذاری فضاهای نام:

در سطح اول نامگذاری فضاهای نام از نام رهیافت استفاده نمایید. به عنوان مثال (ailibrary).
در سطح دوم نامگذاری فضاهای نام از نام فن‌آوری یا محصول (که در بیشتر موارد همنام طرح می‌باشد) و مستقل از نگارش باشد استفاده نمایید.
از نام یک گروه یا بخش سازمان برای نامگذاری فضاهای نام استفاده ننماید چون معمولا این گروه‌ها عمر کوتاهی داشته و پس از مدتی حذف می‌شوند.نام فضاهای نام باید طوری انتخاب گردد که دارای طول عمر زیادی باشد.

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

در حالت کلی اسامی نوع‌ها باید به لحاظ دستوری از نوع اسم باشند. اسامی باید برای دید برنامه‌نویس انتخاب گردد و کاربرد مورد نظر را کاملا روشن نماید. توجه کنید که قالب‌ها بسته به تعریف مورد نظر، می‌توانند تابع، ساختار و یا رده در نظر گرفته شوند و بر اساس تعریف خود از قوانین نوع مورد نظر تبعیت می‌نمایند.

نام ساختارها، رده‌ها و داده‌های و دادده‌های شمارشی را از نوع اسم، اسم جمع و گهگاه صفت انتخاب نموده و از روش نامگذاری زیر خط دار استفاده نمایید.
تا حد امکان نام ساختار یا رده مشتق به نام ساختار یا رده پایه منتهی گردد. به عنوان مثال binary_pixel که از کلاس pixel ارث برده است در انتهای نام خود نام پایه (pixel) را نیز ذکر کرده است.
اعضای داده‌های شمارشی را با استفاده از روش نامگذاری حروف بزرگ نامگذاری نمایید.
به ابتدای نام اعضای داده‌های شمارشی، نام داده شمارشی را نیز اضافه نمایید. به عنوان مثال اگر داده شمارشی به نام rgb_channel وجود داشته باشد، اعضای آن عبارتند از: RGB_CHANNEL_RED، RGB_CHANNEL_GREEN و RGB_CHANNEL_BLUE.
نام اعضای داده‌های شمارشی را غیر جمع انتخاب نمایید مگر اینکه اعضای داده شمارشی از نوع بیتی باشند.
در صورت تعریف یک اشاره‌گر تابع به انتهای نام آن پسوند callback نیز اضافه گردد.قواعد نامگذاری اعضا:

نام متدها را از نوع فعل یا گروه فعلی انتخاب نمایید.توجه نمایید که نیازی نیست نام متد را طوری انتخاب نمایید که نحوه پیاده سازی متد را شرح دهد.

اعضایی که مقدار منطقی هستند و یا متدهایی را که مقدار منطقی برمی‌گردانند به شکل مثبت نامگذاری کنید. به عنوان مثال can_seek بهتر از cant_seek می‌باشد. و همچنین در صورت لزوم می‌توانید از پیشوندهای can، is و has در نام استفاده نمایید.
نام فیلدها را از نوع اسم یا اسم جمع انتخاب نمایید.
نام فیلدها را با استفاده از روش زیر خط دار نامگذاری نمایید و ابتدای نام فیلدها یک زیر خط نیز اضافه نمایید.دقت کنید که فیلدهایی با دسترسی عمومی نباید وجود داشته باشد و فیلدها باید توسط متدها قابل دسترسی باشند.

برای دسترسی به یک فیلد از بیرون به ابتدای متد مربوطه get یا set اضافه نمایید.قواعد نامگذاری پارامترها:

نام پارامترها را با استفاده از روش زیر خط دار نامگذاری نمایید و ابتدای نام پارامترها یک زیر خط نیز اضافه نمایید.
نام پارامترها را طوری انتخاب کنید که نام انتخاب شده، شرح پارامتر نیز باشد.
نام پارامترها را بر اساس معنی آن انتخاب نموده و این انتخاب بر اساس نوع پارامتر نباشد.
پارامتر T در قالب‌ها از قوانین نامگذاری ثوابت تبعیت می‌کند.رهنمودهای طراحی نوع‌ها:

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

از فضاهای نام برای دسته‌بندی نوع‌ها استفاده نمایید.
از فضاهای نام تو در توی عمیق بیهوده بپرهیزید.
از ایجاد بیش از حد فضاهای نام بپرهیزید.
از قراردادن نوع‌های پیشرفته در همان فضای نامی که نوع‌های معمول قرار دارند بپرهیزید. به عنوان مثال ممکن است فضای نام به شکل: ailibrary::image_processing::filters وجود داشته باشد و فضای نام دیگری به شکل ailibrary::image_processing::filters::advanced نیز تعریف گردد.
حتما تمامی نوع‌ها حداقل در یک فضای نام قرار گیرند و نوعی بدون فضای نام نباشد.انتخاب بین ساختار و رده:

زمانی یک ساختار را انتخاب نمایید که نوع مورد نظر کوچک بوده (معمولا کوچک‌تر از 16 بایت) و دارای طول عمر کوتاهی باشد و معمولا درون دیگر اشیا به کار می‌رود و همچون داده‌های اولیه (مثل int) به کار می‌رود.
ساختارها را به تنهایی درون سرآیند تعریف نموده و رده‌ها را هم در سرآیند و هم در پرونده کد پیاده‌سازی نمایید.طراحی رده‌های مجرد:

در رده‌های مجرد سازنده و مخرب تعریف ننمایید و در صورت لزوم این سازنده‌ها و مخرب‌ها عمومی نبوده و محافظت شده باشند.
حداقل یک رده غیر مجرد که از رده مجرد ارث می‌برد موجود باشد.
تا حد امکان از ایجاد رده‌های مجردی که هیچ عضوی ندارند خودداری نمایید.طراحی داده‌های شمارشی:

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

رهنمودهای سربارگذاری:

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

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

تمامی فیلدها باید محافظت شده و یا خصوصی باشند. در صورت نیاز به تغییر فیلد از خارج از ساختار یا رده باید متدهای get و set مربوطه را نوشت. دقت کنید برای سرعت بیشتر در صورت امکان این نوع متدها را به صورت درون خطی (inline) تعریف نمایید.
نامگذاری فیلدها به شکل زیر خط دار و یک زیر خط در ابتدای نام آورده شود.رهنمودهای متدها:

در صورتی که یک متد اعضای رده را تغییر نمی‌دهد (مثل متدهای get) آن را const نمایید. البته برای متدهای ایستا نیازی به این کار نیست.رهنمودهای سربارگزاری عملگرها:

تا آن‌جا که ممکن است از سربارگزاری عملگرها خودداری نمایید مگر اینکه ساختار یا رده مورد نظر شبیه داده‌های اولیه (مثل int) باشد.رهنمودهای پارامترها:

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

اعضای مجازی:

عضوی را مجازی نسازید مگر اینکه دلیل مناسبی برای این کار داشته باشید چرا که اعضای مجازی هزینه زیادی را برای توسعه در آینده متحمل می‌نمایند.
تا جایی که ممکن است اعضای مجازی را عمومی نکنید و در صورت لزوم عضو عمومی از عضو مجازی استفاده نماید.رهنمودهای خطاگردانی:

از کد برای برگرداندن خطا استفاده ننمایید.
خطاهایی که ممکن است برنامه‌نویس انجام دهد (مثل مقادیر نامعتبر برای پارامترها، فراخوانی نابجای یک متد و ...) را با assert خطاگردانی کرده و خطاهای تولید شده توسط سیستم (مثل عدم امکان اختصاص حافظه، عدم وجود یک پرونده و ...) را با تولید یک exception خطاگردانی نمایید.
هنگام تولید exception شی‌ای که باید throw شود از نوع std::runtime_error باشد.
هر خطا هنگام تولید دارای یک شرح باشد.
شرح خطاها به نقطه ختم گردند و حاوی علامت سوال و علامت تعجب نباشند.
تا آن‌جا که امکان دارد از try-catch استفاده ننمایید تا خطاهای تولید شده به سطح بالاتر انتقال پیدا کنند.رهنمودهای حق‌نشر:

به ابتدای پرونده‌های کد متن زیر را اضافه نمایید: <One line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <company> This program is free software: you can redistribute it and/or modify it under the terms of the Hooshafzar License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Hooshafzar License for more details. Web site: <web site> Contact email: <email>

در صورتی که در پیاده‌سازی از کد خاصی استفاده و یا اقتباس گردیده است باید منبع به شکل کامل و به همراه نشانی (در صورت امکان نشانی اینترنتی) پس از متن بالا ذکر گردد.رهنمودهای مستندسازی:

مستندات درون کد به زبان انگلیسی و ساده باشند.
تمامی توابع، ماکروها، ثوابت، ساختارها، داده‌های شمارشی، رده‌ها، اعضا، پارامترها و ... در سرآیند مستندسازی گردند. در مستندسازی سرآیندها نیازی به شرح روش پیاده‌سازی نمی‌باشد.
نحوه پیاده‌سازی متدها و توابع در ابتدای متد یا تابع به زبان انگلیسی توضیح داده شود. همچنین در صورت لزوم منبع نیز ذکر گردد.
روش مستندسازی سرآیندها باید بر اساس نرم‌افزار doxygen (http://www.stack.nl/~dimitri/doxygen) باشد.منابع:

http://msdn2.microsoft.com/en-us/library/ms229042.aspx (http://msdn2.microsoft.com/en-us/library/ms229042.aspx)