Yusefnejad

یوسف نژاد

Yusefnejad

یوسف نژاد

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

عبارات مخفف

در حالت کلی استفاده از عبارات مخفف در نامگذاری توصیه نمی‌شه مگر اینکه عبارت موردنظر بسیار رایج باشه و خواننده بلافاصله متوجه مفهومش بشه. برای مثال HTML ، XML ، IO و UI بسیار رایج هستن، اما باید از بکاربردن عبارات مخفف غیررایج در نامگذاری پرهیز کرد.

برای تشخیص اینکه آیا یک عبارت مخفف رایج هست (تا بشه از اون در نامگذاری استفاده کرد) یا نه، میشه از یه روش بسیار ساده استفاده کرد. برای اینکار کافیه تا عبارت موردنظر رو در گوگل جستجو کنیم و اگه اولین نتایج بدست اومده مربوط به مفهوم موردنظر باشه میشه نتیجه گرفت که اون عبارت مخفف به اندازه کافی رایج هست.

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

براساس تعریف، یک مخفف حداقل باید 2 حرف داشته باشه. نحوه برخورد با مخفف‌های دارای بیشتر از 2 حرف با مخفف‌های دارای 2 حرف با هم فرق داره (دلیل اصلی این اختلاف، جلوگیری از بروز اشتباه به دلیل کمی تعداد کاراکترهاست). با مخفف‌های دارای 2 حرف مانند کلمه‌ای یک حرفی برخورد می‌شه، درصورتی‌که با سایر مخفف‌ها مثل یک کلمه کامل چندحرفی برخورد می‌شه. برای مثال IOStream برای روش PascalCasing و ioStream برای روش camelCasing،  هم‌چنین از HtmlBody و htmlBody به‌ترتیب برای روش‌های Pascal و camel استفاده می‌شه.

نکته:  هیچیک از حروف یک عبارت مخفف در ابتدای یک واژه نام‌گذاری‌شده به روش camelCasing به‌صورت بزرگ نوشته نمی‌شه!

موارد زیادی رو میشه پیدا کرد که در ابتدا به‌نظر می‌رسه برای پیاده‌سازیشون باید قوانین اشاره شده رو نقض کرد. این موارد شامل استفاده از کتابخونه‌های سایر پلتفرم‌ها (مثل MFC, HTML و غیره)، جلوگیری از مشکلات جغرافیایی (مثلا نام کشورها)، احترام به نام افراد درگذشته، و مواردی از این دست می‌شه. اما در بیشتر این موارد هم میشه بدون نقض قوانین فوق و با تغییر عبارت اصلی (که موجب تطابق با این قوانین می‌شه) بدون اینکه لطمه‌ای به مفهومش بزنه، نام‌گذاری رو انجام داد.
تنها موردی که به‌نظر می‌رسه می‌تونه قوانین فوق رو نقض کنه «نام‌های تجاری» اند. البته استفاده از نام‌های تجاری توصیه نمی‌شه، چون این نام‌ها معمولا سریع‌تر از محتوای کتابخونه‌ها تغییر می‌کنن!
برای درک بهتر قانون «عدم استفاده از عبارات مخففی که رایج نیستند» مثالی از زبان توسعه دهندگان دات‌نت‌فریمورک آورده میشه. در کلاس Color متد زیر با Overloadهای مختلف وجود داره:

public class Color {
    …
    public static Color FromArgb (…)
    {
      …
    }
}

در این مورد برای رعایت قوانین به‌جای استفاده از ARGB از عبارت Argb استفاده شده. اما بکارگیری این عبارت موجب شده تا این سوال به‌ظاهر خنده‌دار اما درست پیش‌ بیاد: «چیجوری میشه در این کلاس، یک رنگ رو از ARGB تبدیل کرد؟ هرچی که من میبینم فقط تبدیل از طریق آرگومان b (یا Argb ) هست.»
خب حالا به‌نظر می‌رسه که در اینجا باید قوانین رو نقض کرد و از عنوان FromARGB که مفهوم درست رو می‌رسونه استفاده کرد. اما با کمی دقت متوجه می‌شیم که این قوانین در ابتدا نیز با پیاده‌سازی نشون داده شده نقض شدن! یعنی چی؟ خب، همه می‌دونیم که عبارت RGB مخفف معروفی برای عبارت Red Green Blue  هست. اما استفاده از ARGB برای افزودن کلمه Alpha به ابتدای عبارت مذکور چندان رایج نیست. پس استفاده از مخفف Argb از همون اول اشتباه بوده. بنابراین راه‌حل بهتر می‌تونه استفاده از نام FromAlphaRgb باشه که هم قوانین فوق رو نقض نکرده و هم مفهوم رو بهتر می‌رسونه.

زبانهای برنامه نویسی

عبارات و کلماتی که مختص یک زبان برنامه نویسی خاص (مثل int یا long در #C) هستند رو نباید به عنوان نام یا بخشی از نام یکی از اجزای برنامه انتخاب کرد. مثلا برای دریافت مقدار عددی یک شی نباید از نامی مثل GetInt استفاده کرد. برای این کار میشه از نامی مناسبتر با مفهومی معنادار مثل GetLength استفاده کرد.
در مواردی که به دلایل مختلف نشه از روش بالا استفاده کرد بهتره به جای استفاده از عبارات مختص یک زبان برنامه نویسی در صورت امکان از معادل کلی تر اون در CLR استفاده کرد. مثلا برای متدی که تبدیلی به نوع Int64 انجام میده، به جای استفاده از نام GetLong یا ToLong بهتره از GetInt64 یا ToInt64 استفاده بشه.
درمواردی که نشه یک عبارت معنادار مناسب یافت، و همچنین نوع پارامتر یا مقدار مربوطه مهم نباشه، بهتره از کلماتی کلی و معمول مثل item یا value استفاده بشه. مثل:

void Write(double value);
void Write(float value);
void Write(short value);

نکته جالبی که بد نیست در اینجا بهش اشاره بشه اینه که تو VB.NET یه سری کلمه های کلیدی همنام با کلاسهای پیاده شده در کتابخونه های پایه ای دات نت وجود دارن. مثل Delegate یا Module و یا Application. با اینکه ویژوال بیسک هم مثل سی شارپ روشی برای جداسازی کلمه های کلیدی از نام اجزا داره (با استفاده از []) اما استفاده از این نامها در طراحی این زبون برنامه نویسی یک نقطه ضعف به حساب میاد.

یکی دیگه از نقاط ضعف طراحی در دات نت، نامگذاری استثنا بسیار معرف NullReferenceException هست. استفاده از این کلاس در VB.NET با توجه به اینکه این زبون از عبارت Nothing به جای null استفاده میکنه، یک عیب به حساب میاد. یعنی در نامگذاری این استثنا، قاعده اشاره شده در این قسمت رعایت نشده و از کلمه ای مخصوص یک زبان برنامه نویسی (در اینجا عبارت null که مثلا مخصوص #C هست) استفاده شده.

نسخه های جدید

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


public class AppDomain
{
  /// <summary>
  /// Establishes the specified directory path as the location where assemblies are shadow copied.
  /// </summary>
  /// <param name="path">The fully qualified path to the shadow copy location. </param><exception cref="T:System.AppDomainUnloadedException">The operation is attempted on an unloaded application domain. </exception><filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="ControlAppDomain"/></PermissionSet>
  [Obsolete("AppDomain.SetCachePath has been deprecated. Please investigate the use of AppDomainSetup.CachePath instead. http://go.microsoft.com/fwlink/?linkid=14202")]
  [SecurityCritical]
  [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
  public void SetCachePath(string path)
  {
    InternalSetCachePath(path);
  }
}

public class AppDomainSetup
{
  /// <summary>
  /// Gets or sets the name of an area specific to the application where files are shadow copied.
  /// </summary>
  /// 
  /// <returns>
  /// The fully qualified name of the directory path and file name where files are shadow copied.
  /// </returns>
  /// <filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/></PermissionSet>
  public string CachePath
  {
    [SecuritySafeCritical] get
    {
      return VerifyDir(Value[9], false);
    }
    set
    {
      Value[9] = NormalizePath(value, false);
    }
  }
}

- اگه احساس میشه که باید عبارتی به نام قدیمی اضافه بشه بهتره از پسوند به جای پیشوند استفاده کرد. این روش کمک زیادی هنگام مطالعه سندها و یا هنگام استفاده از Intellisense و یا گشتن در لیست اجزای یک برنامه میکنه. مثل ReaderWriterLockSlim به عنوان نسخه جدید کلاس ReaderWriterLock به جای استفاده از SlimReaderWriterLock، با اینکه از لحاظ زبون انگلیسی خوانایی دومی بهتره اما برای رعایت قاعده اشاره شده از همون نسخه اولی استفاده شده.

- سعی کنید تا اونجا که ممکنه از عباراتی جدید و با معنا که به روشنی تغییرات اعمال شده رو برسونه، به جای افزودن پسوند یا پیشوند استفاده کنین.

- اگه نام قدیمی تنها عبارتیه که مفهوم درست رو در بر داره (مثل نام یک استاندارد صنعتی)، و نشه از پسوند و پیشوندی مناسب برای نسخه جدید استفاده کرد، از یک پسوند عددی برای متمایز کردن نسخه جدید استفاده کنین. مثل IDynamicObject2
مثال:
// old API
[Obsolete("This type is obsolete. Please use the new version of the same class, X509Certificate2.")]
public class X509Certificate { ... }

// new API
public class X509Certificate2 { ... }

- نباید از پسوندهایی مثل Ex (که در نسخه های قدیمی کتابخونه های زبان ++C زیاد استفاده میشه) برای مشخص کردن نسخه های جدید استفاده کرد.
مثال:
[Obsolete("This type is obsolete. ...")]
public class Car { ... }
 
// new API
public class CarEx      { ... }  // اشتباه
public class CarNew     { ... }  // اشتباه

public class Car2 { ... } // درست public class Automobile { ... } // درست

- درصورت نیاز برای نامگذاری نسخه جدیدی از برنامه که مثلا بر روی محدوده وسیعتری از اعداد کار میکنه، میشه از پسوند عددی 64 استفاده کرد. اینکار تنها در صورتیکه یک نسخه قدیمی برای کار با اعداد با محدوده کوچکتر (مثلا اعداد 32 بیتی) وجود داشته باشه، درسته.
مثال:
public class Process
{
  // old API
  public int  PeakWorkingSet { get; set; }
  public int  PagedMemorySize { get; set; }
  // ...
  // new API
  public long  PeakWorkingSet64 { get; set; }
  public long  PagedMemorySize64 { get; set; }
}

نکته: توجه کنین که این قاعده تنها برای قسمتهایی که از قبل منتشر شدن و پیاده سازی نسخه های جدید در انتشار جدید کتابخانه ها باید استفاده بشه. برای حالات مشابه ای که هنوز نسخه ای از کتابخانه منتشر نشده، باید پیاده سازی های موجود تمامی انواع رو پشتیبانی کنه و نباید از این روش استفاده کرد. در این مواقع بهتره از تکنیک overloading استفاده بشه.

کلمات مرکب

کلمات مرکب به کلماتی گفته می‌شه که بیش از یک کلمه با مفهوم مستقل در ساختش استفاده شده باشه. مثل Callback یا FileName. با تمام کلمات موجود در یک کلمه مرکب مثل یک کلمه مستقل رفتار نمیشه (یعنی حرف اولشون بزرگ نوشته بشه). میپرسید یعنی چی؟
کلمات مرکبی وجود دارند که به اونا closed-form گفته میشه. این نوع کلمات مرکب با اینکه از 2 یا چند کلمه دارای مفهوم مستقل تشکیل شدن، اما به‌ خودی‌ خود دارای مفهوم جداگانه و مستقلی هستند. برای تشخیص این کلمات میشه به فرهنگ لغت مراجعه کرد (و یا از نرم‌افزار Microsoft Word استفاده کرد) و دریافت که آیا کلمه مرکب موردنظر آیا مفهوم مستقلی برای خودش داره یا نه.

نکته: کلمات مرکب از نوع closed-form مثل یک کلمه ساده و کامل نوشته میشن.

در جدول زیر مثال‌هایی از عبارات رایج و نحوه درست و نادرست استفاده از هریک نشان داده شده است:

Pascal Casing Camel Casing Wrong
Callback callback CallBack
BitFlag bitFlag Bitflag / bitflag
Canceled canceled Cancelled
DoNot doNot Donot / Don’t
Email email EMail
Endpoint endpoint EndPoint / endPoint
FileName fileName Filename / filename
Gridline gridline GridLine / gridLine
Hashtable hashtable HashTable / hashTable
Id id ID
Indexes indexes Indices
LogOff logOff Logoff / LogOut
LogOn logOn Logon / LogIn
SignOut signOut Signout / SignOff
SignIn signIn Signin / SignOn
Metadata metadata MetaData / metaData
Multipanel multipanel MultiPanel / multiPanel
Multiview multiview MultiView / multiView
Namespace namespace NameSpace / nameSpace
Ok ok OK
Pi pi PI
Placeholder placeholder PlaceHolder / placeHolder
UserName username Username / username
WhiteSpace whiteSpace Whitespace / whitespace
Writable writable Writeable / writeable

همونطور که در جدول بالا آورده شده، در استفاده از قوانین عبارات مخفف دو مورد استثنا وجود داره: Id و Ok. این دو مورد به دلیل رواج و کاربرد عامیانه زیادشون به این شکل نوشته میشن. این دو کلمه باید همینجوری که در اینجا نشون داده شده استفاده بشن.

نامگذاری اجزا

در جدول زیر خلاصه ای از قواعد نامگذاری اجزای مختلف یک برنامه آورده شده:

جزء روش نامگذاری مثال
Assembly Pascal
Kara.Pos.App.exe
Namespace Pascal
namespace System.Security { ... }
Type Pascal
public class StreamReader { ... }
Interface Pascal
public interface IEnumerable { ... }
Method Pascal
public virtual string ToString();
Property Pascal
public int Length { get; }
Event Pascal
public event EventHandler Exited;
Field Pascal
public static readonly TimeSpan InfiniteTimeout;

public const Min = 0;
Enum value Pascal
public enum FileMode {
  Append,
  ...
}
Parameter Camel
public static int ToInt32(string value);

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

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="">
تجدید کد امنیتی
آخرین نظرات