اشتراک‌ها
تست خودکار API های سمت سرور توسط Mocha و Chai و TypeScript در VSCode

This project uses mochachaitypescript and vs code debug toghether, so you can write your api tests easily. 

This is useful for scenarios when you've some api developed in python for example, but you'd prefer to develop tests in typescript/javascript.

Another use case is when you've some legacy api and you want to develop some tests to make [risk free change] of your legacy api possibel! 

تست خودکار API های سمت سرور توسط Mocha و Chai و TypeScript در VSCode
اشتراک‌ها
ایجاد Responsive jQuery Pop-Up Gallery
in this tutorial you will lean how to create a an awesome popup gallery. Each gallery will have a small preview animation. This tutorial will provide you with five different popup galleries. All the main animations are done using CSS transitions. I would of liked to build the entire thing using CSS only but unfortunately this was a pretty complex gallery so i had to use some JavaScript.  Demo
ایجاد Responsive jQuery Pop-Up Gallery
اشتراک‌ها
استفاده از LINQ در JavaScript
One of the more awesome things I like about being a .NET developer is LINQ. LINQ (Language Integrated Query) is a fluent query interface implemented in the .NET framework. It helps you query, sort and order any type of collection. This is a very neat way of querying arrays, lists, dictionaries, objects, etc. I’ve made 5 examples which run out of the box with Node.js (or io.js). You can also use the library for browser based JavaScript projects.
استفاده از LINQ در JavaScript
اشتراک‌ها
کتابخانه canvasjs
An easy to use HTML5 JavaScript Charting library built on Canvas element. Charts can render across devices including iPhone, iPad, Android, Windows Phone, Desktops, etc. This allows you to create rich dashboards that can work across devices without compromising on maintainability or functionality of your web application. Graphs include several good looking themes and are 10x faster than conventional Flash / SVG based Libraries – resulting in lightweight, beautiful and responsive dashboards.
کتابخانه canvasjs
مطالب
CoffeeScript #14

قسمت‌های اصلاح نشده

CoffeeScript در حال رفع برخی از معایب طراحی جاوااسکریپت است و این راه، بس طولانی است. همانطور که قبلا گفته شد، CoffeeScript به شدت به تجزیه و تحلیل استاتیک در زمان طراحی محدود شده است و هیچ بررسی در زمان اجرایی را برای بهبود کارآیی آن انجام نمی‌دهد.
CoffeeScript از یک کامپایلر مستقیم منبع به منبع استفاده می‌کند. با این دیدگاه که هر دستور در CoffeeScript در نتیجه به یک دستور معادل در جاوااسکریپت تبدیل می‌شود.
CoffeeScript برای همه‌ی کلمات کلیدی جاوااسکریپت، کلمه‌ی معادلی ایجاد نمی‌کند، مانند typeof؛ و همچنین برخی از معایب طراحی جاوااسکریپت، به CoffeeScript نیز اعمال می‌شود.
در دو قسمت قبل + و + بر روی معایب طراحی در جاوااسکریپت که توسط CoffeeScript اصلاح شده بود، توضیح دادیم. حال می‌خواهیم درباره برخی از معایب جاوااسکریپت که CoffeeScript تا به حال نتوانسته است آنها را اصلاح کند صحبت کنیم.

استفاده از eval

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

تابع eval یک رشته از کد جاوااسکریپت را در حوزه‌ی محلی اجرا می‌کند و توابعی مانند setTimeout و setInterval نیز می‌توانند در آرگومان اولشان یک رشته از کد جاوااسکریپت را دریافت و ارزیابی کنند.

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

# Don't do this
model = eval(modelName)

# Use square brackets instead
model = window[modelName]

استفاده از typeof

اپراتور typeof احتمالا بزرگترین نقص طراحی جاوااسکریپت است؛ تنها به این دلیل که اساسا به طور کامل شکست خورده است. در واقع از آن فقط یک استفاده می‌شود تا تشخیص داده شود که یک مقدار undefined است یا نه.

typeof undefinedVar is "undefined"
برای چک کردن type همه types، متاسفانه typeof نمی تواند به درستی این کار را انجام دهد و مقدار بازگشتی آن وابسته به مرورگر و چگونگی نمونه سازی آن نمونه است. در این رابطه CoffeeScript هیچ کمکی به شما نمی‌تواند بکند، چرا که قبلا نیز گفته شد، CoffeeScript یک زبان با تجزیه و تحلیل استاتیک است و هیچ بررسی در زمان اجرایی بر روی نوع آن ندارد.
در اینجا لیستی از مشکلات، هنگام استفاده از typeof را مشاهده می‌کنید:
Value               Class      Type
----------------------------------------------
"foo"               String     string
new String("foo")   String     object
1.2                 Number     number
new Number(1.2)     Number     object
true                Boolean    boolean
new Boolean(true)   Boolean    object
new Date()          Date       object
new Error()         Error      object
[1,2,3]             Array      object
new Array(1, 2, 3)  Array      object
new Function("")    Function   function
/abc/g              RegExp     object
new RegExp("meow")  RegExp     object
{}                  Object     object
new Object()        Object     object
همانطور که مشاهده می‌کنید تعریف یک رشته در داخل "" و یا با کلاس String، در نتیجه‌ی استفاده از typeof تاثیر گذار است. به طور منطقی typeof باید "string" را به عنوان خروجی در هر دو حالت نشان دهد، اما برای دومی به صورت "object" باز می‌گرداند.
سوالی که اینجا مطرح می‌شود این است که ما چطور می‌توانیم یک نوع را در جاوااسکریپت چک کنیم؟
خوب، خوشبختانه ()Object.prototype.toString ما را نجات داده است. اگر ما این تابع را بر روی یک شیء خاص فراخوانی کنیم، مقدار صحیح را بر می‌گرداند.
در اینجا مثالی از نحوه‌ی پیاده سازی jQuery.type را مشاهده می‌کنید:
type = do ->
  classToType = {}
  for name in "Boolean Number String Function Array Date RegExp Undefined Null".split(" ")
    classToType["[object " + name + "]"] = name.toLowerCase()

  (obj) ->
    strType = Object::toString.call(obj)
    classToType[strType] or "object"

# Returns the sort of types we'd expect:
type("")         # "string"
type(new String) # "string"
type([])         # "array"
type(/\d/)       # "regexp"
type(new Date)   # "date"
type(true)       # "boolean"
type(null)       # "null"
type({})         # "object"
در صورتیکه بخواهید تشخیص دهید یک متغیر تعریف شده است یا نه، باید از typeof استفاده کنید؛ در غیر این صورت پیام خطای ReferenceError را دریافت خواهید کرد.
if typeof aVar isnt "undefined"
  objectType = type(aVar)
و یا به طور خلاصه‌تر با استفاده از اپراتور وجودی:
objectType = type(aVar?)
راه دیگری برای چک کردن نوع، استفاده از اپراتور وجودی CoffeeScript است. برای مثال: می‌خواهیم یک مقدار را در یک آرایه اضافه کنیم. می‌توان گفت تا زمانیکه تابع push پیاده سازی شده باشد ما باید با آن مانند یک آرایه رفتار کنیم.
anArray?.push? aValue
اگر anArray یک شیء به غیر از آرایه باشد، اپراتور وجودی تضمین خواهد کرد که هیچگاه تابع push فراخوانی نخواهد شد.

استفاده از instanceof

کلمه‌ی کلیدی instanceof نیز تقریبا همانند typeof شکست خورده است. در حالت ایده آل، instanceof، سازنده‌ی دو شیء را با هم مقایسه می‌کند، در صورتیکه یک شیء نمونه‌ای از شیء دیگر باشد، یک مقدار boolean را باز می‌گرداند. در واقع instanceof موقعی کار مقایسه را انجام می‌دهد که اشیاء، سفارشی سازی شده باشند. وقتی عمل مقایسه می‌خواهد بر روی این نوع اشیاء سفارشی سازی شده، انجام شود، استفاده از typeof بی‌فایده است.

new String("foo") instanceof String # true
"foo" instanceof String             # false
علاوه بر این، instanceof همچنین بر روی اشیاء در فریم‌های مختلف مرورگر عمل مقایسه را نمی‌تواند انجام دهد. در واقع instanceof فقط نتیجه‌ی صحیح مقایسه را در اشیاء سفارشی سازی شده برمی‌گرداند؛ مانند کلاس‌های CoffeeScript.
class Parent
class Child extends Parent

child = new Child
child instanceof Child  # true
child instanceof Parent # true
مواقعی از instanceof استفاده کنید که مطمئن هستید بر روی اشیای ساخته شده توسط شما بکار گرفته می‌شود و یا هرگز از آن استفاده نکنید.

استفاده از delete

از کلمه کلیدی delete برای حذف خصوصیات موجود در اشیاء به صورت کاملا مطمئن، می‌توان استفاده کرد.
anObject = {one: 1, two: 2}
delete anObject.one
anObject.hasOwnProperty("one") # false
هر نوع استفاده دیگر، از قبیل حذف متغیرها و یا توابع کار نخواهد کرد.
aVar = 1
delete aVar
typeof Var # "integer"
در صورتیکه می‌خواهید یک اشاره گر به یک متغیر را حذف کنید فقط کافیست مقدار null را به آن انتساب دهید.
aVar = 1
aVar = null

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


حالت‌های مختلف ذخیره سازی اطلاعات در مرورگر کاربر

Web Storage و یا Client-side storage در دو حالت کلی session storage و local storage قابل دسترسی است:
الف) session storage
در این حالت اطلاعات ذخیره شده‌ی در session storage، پس از بسته شدن مرورگر، به صورت خودکار حذف خواهند شد.

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

هر دو حالت فوق به صورت ایزوله ارائه می‌شوند؛ با محدودیت حجم 10 مگابایت (جمع حجم نهایی هر دو حالت با هم، محدود به 10 مگابایت است). به این معنا که برنامه‌های هر دومین، تنها به محل ذخیره سازی خاص همان دومین دسترسی خواهند داشت.
همچنین API دسترسی به آن‌ها synchronous است و کار کردن با آن‌ها ساده‌است.

البته Client-side storage به دو مورد فوق خلاصه نمی‌شود و شامل File Storage ،WebSQL ،IndexedDB و کوکی‌های مرورگر نیز هست.
- File Storage هنوز مراحل آزمایشی خودش را طی می‌کند و مناسب برنامه‌های دنیای واقعی نیست.
- WebSQL قرار بود بر اساس بانک اطلاعاتی معروف SQLite ارائه شود؛ اما W3C در سال 2010 این استاندارد را منسوخ شده اعلام کرد و با IndexedDB جایگزین شد. دسترسی به آن async است و می‌تواند موضوع بحثی مجزا باشد.
- کوکی‌های مرورگرها نیز یکی دیگر از روش‌های ذخیره سازی اطلاعات در مرورگرها هستند و تنها به ذخیره سازی حداکثر 4096 بایت اطلاعات محدود هستند. کوکی‌ها نیز همانند local storage پس از بسته شدن مرورگر باقی می‌مانند؛ اما برخلاف آن، دارای تاریخ انقضاء و همچنین قابلیت ارسال بین دومین‌ها را نیز دارا می‌باشند. اگر تاریخ انقضای یک کوکی تعیین نشود، همانند session storage، در پایان کار مرورگر و بسته شدن آن، حذف خواهد شد.


تهیه یک سرویس Angular برای کار با Web Storage

جهت کپسوله سازی نحوه‌ی کار با session storage و local storage می‌توان سرویسی را برای این‌کار تهیه کرد:
import { Injectable } from "@angular/core";

@Injectable()
export class BrowserStorageService {

  getSession(key: string): any {
    const data = window.sessionStorage.getItem(key);
    return JSON.parse(data);
  }

  setSession(key: string, value: any): void {
    const data = value === undefined ? null : JSON.stringify(value);
    window.sessionStorage.setItem(key, data);
  }

  removeSession(key: string): void {
    window.sessionStorage.removeItem(key);
  }

  removeAllSessions(): void {
    for (const key in window.sessionStorage) {
      if (window.sessionStorage.hasOwnProperty(key)) {
        this.removeSession(key);
      }
    }
  }

  getLocal(key: string): any {
    const data = window.localStorage.getItem(key);
    return JSON.parse(data);
  }

  setLocal(key: string, value: any): void {
    const data = value === undefined ? null : JSON.stringify(value);
    window.localStorage.setItem(key, data);
  }

  removeLocal(key: string): void {
    window.localStorage.removeItem(key);
  }

  removeAllLocals(): void {
    for (const key in window.localStorage) {
      if (window.localStorage.hasOwnProperty(key)) {
        this.removeLocal(key);
      }
    }
  }
}
دسترسی به local storage از طریق شیء window.localStorage انجام می‌شود و کار با آن در برنامه‌های Angular، نیاز به وابستگی خاص دیگری ندارد. این مورد برای کار با session storage از طریق شیء window.sessionStorage صورت می‌گیرد. هر دو حالت، دارای متدهای setItem برای ذخیره سازی اطلاعات، getItem برای دریافت اطلاعات، بر اساس کلیدی مشخص و removeItem برای حذف اطلاعات کلیدی معلوم، هستند.
در حالت setItem اطلاعاتی را که مرورگرها ذخیره می‌کنند باید رشته‌ای باشد. به همین جهت توسط متد JSON.stringify می‌توان یک شیء را تبدیل به رشته کرد و ذخیره نمود و در حالت getItem توسط متد JSON.parse، می‌توان این رشته را مجددا به همان شیء پیشین خود تبدیل کرد و بازگشت داد.


محل صحیح تعریف BrowserStorageService

همانطور که در مطلب «سازماندهی برنامه‌های Angular توسط ماژول‌ها» بررسی شد، محل صحیح تعریف این سرویس سراسری مشترک در بین کامپوننت‌ها و ماژول‌های برنامه، در CoreModule و پوشه‌ی src\app\core\browser-storage.service.ts است:
import { BrowserStorageService } from "./browser-storage.service";
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterModule } from "@angular/router";

@NgModule({
  imports: [CommonModule, RouterModule],
  exports: [], // components that are used in app.component.ts will be listed here.
  declarations: [], // components that are used in app.component.ts will be listed here.
  providers: [BrowserStorageService] // singleton services of the whole app will be listed here.
})
export class CoreModule { };

و CoreModule نیز به AppModule اضافه می‌شود:
import { CoreModule } from "./core/core.module";

@NgModule({
  imports:      [
//...
    CoreModule,
//...
    RouterModule.forRoot(appRoutes)
  ],
//...
})
export class AppModule { }

بنابراین یکی دیگر از روش‌های به اشتراک گذاری اطلاعات در بین قسمت‌های مختلف برنامه، ذخیره سازی آن‌ها در session/local storage و سپس بازیابی آن‌ها بر اساس کلیدهای مشخص آن‌ها است.


مثالی از نحوه‌ی کاربرد BrowserStorageService

برای آزمایش سرویس تهیه شده، از کامپوننت و قالب ذیل استفاده خواهیم کرد. در اینجا سرویس BrowserStorageService به سازنده‌ی کلاس تزریق شده‌است و سپس دو حالت session storage و local storage مورد بررسی قرار گرفته‌اند:
import { BrowserStorageService } from "./../../core/browser-storage.service";
import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-browser-storage-sample-test",
  templateUrl: "./browser-storage-sample-test.component.html",
  styleUrls: ["./browser-storage-sample-test.component.css"]
})
export class BrowserStorageSampleTestComponent implements OnInit {

  fromSessionStorage = "";
  fromLocalStorage = ""

  sessionStorageKey = "sessionStorageKey1";
  localStorageKey = "localStorageKey1"

  constructor(private browserStorage: BrowserStorageService) { }

  ngOnInit() {
  }

  sessionStorageSetItem() {
    this.browserStorage.setSession(this.sessionStorageKey, "Val1");
  }

  sessionStorageGetItem() {
    this.fromSessionStorage = this.browserStorage.getSession(this.sessionStorageKey);
  }

  localStorageSetItem() {
    this.browserStorage.setLocal(this.localStorageKey, { key1: "val1", key2: 2 });
  }

  localStorageGetItem() {
    this.fromLocalStorage = JSON.stringify(this.browserStorage.getLocal(this.localStorageKey));
  }
}
به همراه قالب:
<h1>Browser storage sample</h1>
<div class="panel">
  <button class="btn btn-primary" (click)="sessionStorageSetItem()" type="button">sessionStorage -> Set Item</button>
  <button class="btn btn-success" (click)="sessionStorageGetItem()" type="button">sessionStorage -> Get Item</button>
  <div class="alert alert-info" *ngIf="fromSessionStorage">
    {{fromSessionStorage}}
  </div>
</div>

<div class="panel">
  <button class="btn btn-warning" (click)="localStorageSetItem()" type="button">localStorage -> Set Item</button>
  <button class="btn btn-success" (click)="localStorageGetItem()" type="button">localStorage -> Get Item</button>
  <div class="alert alert-info" *ngIf="fromLocalStorage">
    {{fromLocalStorage}}
  </div>
</div>

در این حالت اگر برنامه را اجرا کنیم، یک چنین خروجی قابل مشاهده خواهد بود:


و اگر به برگه‌ی Application کنسول ابزارهای توسعه دهنده‌های مرورگرها نیز مراجعه کنیم، این مقادیر ثبت شده را در دو حالت استفاده‌ی از session storage و local storage، می‌توان مشاهده کرد:



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

اصول و قراردادهای نام‌گذاری در دات‌نت
انواع نام‌گذاری
نام‌گذاری اشیا در حالت کلی را می‌توان به سه روش زیر انجام داد:
1. Pascal Casing: در این روش حرف اول هر کلمه در نام شی به صورت بزرگ نوشته می‌شود.
FirstName
2. camel Casing: حرف اول در اولین کلمه نام هر شی به صورت کوچک و حرف اول بقیه کلمات به صورت بزرگ نوشته می‌شود.
firstName
3. Hungarian: در این روش برای هر نوع شی موجود یک پیشوند درنظر گرفته می‌شود تا از روی نام شی بتوان به نوع آن پی برد. در ادامه و پس از این پیشوندها سایر کلمات بر اساس روش Pascal Casing نوشته می‌شوند.
strFirstName
lblFirstName
نکته: استفاده از این روش به جز در نام‌گذاری کنترل‌های UI منسوخ شده است.

قراردادهای کلی
1. نباید نام اشیا تنها در بزرگ یا کوچک بودن حروف با هم فرق داشته باشند. به عنوان مثال نباید دو کلاس با نام‌های MyClass و myClass داشته باشیم. هرچند برخی از زبان‌ها case-sensitive هستند اما برخی دیگر نیز چنین قابلیتی ندارند (مثل VB.NET). بنابراین اگر بخواهیم کلاس‌های تولیدی ما در تمام محیط‌ها و زبان‌های برنامه نویسی قابل اجرا باشند باید از این قرارداد پیروی کنیم.
2. تا آنجا که امکان دارد باید از به‌کار بردن مخفف کلمات در نام‌گذاری اشیا دوری کنیم. مثلا به جای استفاده از GetChr باید از GetCharacter استفاده کرد.
البته در برخی موارد که مخفف واژه موردنظر کاربرد گسترده ای دارد می‌توان از عبارت مخفف نیز استفاده کرد. مثل UI به جای UserInterface و یا IO به جای InputOutput.
 
آ. اصول نام‌گذاری فضای نام (namespace)
1. اساس نام‌گذاری فضای نام باید از قاعده زیر پیروی کند:
<Company>.<Technology|Produt|Project>[.<Feature>][.<SubNamespace>]
( < > : اجباری        [ ] : اختیاری )
2. برای نام‌گذاری فضای نام باید از روش Pascal Casing استفاده شود.
3. در هنگام تعریف فضاهای نام به وابستگی آنها توجه داشته باشید. به عنوان مثال اشیای درون یک فضای نام پدر نباید به اشیای درون فضای نام یکی از فرزندانش وابسته باشد. مثلا در فضای نام System نباید اشیایی وجود داشته باشند که به اشیای درون فضای نام System.UI وابسته باشند.
4. سعی کنید از نام‌ها به صورت جمع برای عناوین فضای نام استفاده کنید. مثلا به جای استفاده از Kara.CSS.HQ.Manager.Entity از Kara.CSS.HQ.Manager.Entities استفاده کنید. البته برای مورادی که از عناوین مخفف و یا برندهای خاص استفاده کرده‌اید از این قرارداد پیروی نکنید. مثلا نباید از عنوانی شبیه به Kara.CSS.Manager.IOs استفاده کنید.
5. از عنوانی پایدار و مستقل از نسخه محصول برای بخش دوم عنوان فضای نام استفاده کنید. بدین معنی که این عناوین با گذر زمان و تغییر و تحولات در محتوای محصول و یا تولیدکننده نباید تغییر کنند. مثال:
Microsoft.Reporting.WebForms
Kara.Support.Manager.Enums
Kara.CSS.HQ.WebUI.Configuration
6. از عناوین یکسان برای فضای نام و اشیای درون آن استفاده نکنید. مثلا نباید کلاسی با عنوان Manager در فضای نام Kara.CSS.Manager وجود داشته باشد.
7. از عناوین یکسان برای اشیای درون فضاهای نام یک برنامه استفاده نکنید. مثلا نباید دو کلاس با نام Package در فضاهای نام Kara.CSS.Manger و Kara.CSS.Manger.Entities داشته باشید.

ب. اصول نام‌گذاری کلاس‌ها و Structها
1. عنوان کلاس باید اسم یا موصوف باشد.
2. در نام‌گذاری کلاس‌ها باید از روش Pascal Casing استفاده شود.
3. نباید از عناوین مخففی که رایج نیستند استفاده کرد.
4. از پیشوندهای زائد مثل C یا Cls نباید استفاده شود.
5. نباید از کاراکترهایی به غیر از حروف (و یا در برخی موارد خیلی خاص، شماره نسخه) در نام‌گذاری کلاس‌ها استفاده شود.
مثال:
درست:
PackageManager , PacakgeConfigGenerator
Circle , Utility , Package
نادرست:
CreateConfig , classdata
CManager , ClsPackage , Config_Creator , Config1389
6. در نام‌گذاری اشیای Generic از استفاده از عناوینی چون Element, Node, Log و یا Message پرهیز کنید. این کار موجب به‌وجودآمدن کانفلیکت در عناوین اشیا می‌شود. در این موارد بهتر است از عناوینی چون FormElement, XmlNode, EventLog و SoapMessage استفاده شود. درواقع بهتر است نام اشیای جنریک، برای موارد موردنیاز، کاملا اختصاصی و درعین حال مشخص‌کننده محتوا و کاربرد باشند.
7. از عناوینی مشابه عناوین کتابخانه‌های پایه دات‌نت برای اشیای خود استفاده نکنید. مثلا نباید کلاسی با عنوان Console, Parameter, Action و یا Data را توسعه دهید. هم‌چنین از کابرد عناوینی مشابه اشیای موجود در فضاهای نام غیرپایه دات‌نت و یا غیردات‌نتی اما مورداستفاده در پروژه خود که محتوا و کاربردی مختص همان فضای نام دارند پرهیز کنید. مثلا نباید کلاسی با عنوان Page در صورت استفاده از فضای نام System.Web.UI تولید کنید.
8. سعی کنید در مواردی که مناسب به‌نظر می‌رسد از عنوان کلاس پایه در انتهای نام کلاس‌های مشتق‌شده استفاده کنید. مثل FileStream که از کلاس Stream مشتق شده است. البته این قاعده در تمام موارد نتیجه مطلوب ندارد. مثلا کلاس Button که از کلاس Control مشتق شده است. بنابراین در به‌کاربردن این مورد بهتر است تمام جوانب و قواعد را درنظر بگیرید.

پ. اصول نام‌گذاری مجموعه‌ها (Collections)
یک مجموعه در واقع یک نوع کلاس خاص است که حاوی مجموعه‌ای از داده‌هاست و از همان قوانین کلاس‌ها برای نام‌گذاری آن‌ها استفاده می‌شود.
1. بهتر است در انتهای عنوان مجموعه از کلمه Collection استفاده شود. مثال:
CenterCollection , PackageCollection
2. البته درصورتی‌که کلاس مورد نظر ما رابط IDictionary را پیاده‌سازی کرده باشد بهتر است از پسوند Dictionary استفاده شود.

ت. اصول نام‌گذاری Delegateها
1. عنوان یک delegate باید اسم یا موصوف باشد.
2. در نام‌گذاری delegateها باید از روش Pascal Casing استفاده شود.
3. نباید از عناوین مخففی که رایج نیستند استفاده کرد.
4. از پیشوندهای زائد مثل D یا del نباید استفاده شود.
5. نباید از کاراکترهایی به غیر از حروف در نام‌گذاری delegateها استفاده شود.
6. نباید در انتهای نام یک delegate از عبارت Delegate استفاده شود.
7. بهتر است که درصورت امکان در انتهای نام یک delegate که برای Event Handler استفاده نمی‌شود از عبارت Callback استفاده شود. البته تنها درصورتی‌که معنی و مفهوم مناسب را داشته باشد.
مثال:
نحوه تعریف یک delegate
public delegate void Logger (string log);
public delegate void LoggingCallback (object sender, string reason);

ث. اصول نام‌گذاری رویدادها (Events)
1. عنوان یک رویداد باید فعل یا مصدر باشد.
2. در نام‌گذاری کلاس‌ها باید از روش Pascal Casing استفاده شود.
3. نباید از عناوین مخففی که رایج نیستند استفاده کرد.
4. از پیشوندهای زائد نباید استفاده شود.
5. نباید از کاراکترهایی به غیر از حروف در نام‌گذاری رویدادها استفاده شود.
6. بهتر است از پسوند EventHandler در عنوان هندلر رویداد استفاده شود.
7. از به کاربردن عباراتی چون AfterXXX و یا BeforeXXX برای نمایش رویدادهای قبل و یا بعد از رخداد خاصی خودداری شود. به جای آن باید از اسم مصدر (شکل ingدار فعل) برای نام‌گذاری رویداد قبل از رخداد و هم‌چنین شکل گذشته فعل برای نام‌گذاری رویداد بعد از رخداد خاص استفاده کرد.
مثلا اگر کلاسی دارای رویداد Open باشد باید از عنوان Openning برای رویداد قبل از Open و از عنوان Opened برای رویداد بعد از Open استفاده کرد.
8. نباید از پیشوند On برای نام‌گذاری رویداد استفاده شود.
9. همیشه پارامتر e و sender را برای آرگومانهای رویداد پیاده سازی کنید. sender که از نوع object است نمایش دهنده شیی است که رویداد مربوطه را به وجود آورده است و e درواقع آرگومانهای رویداد مربوطه است.
10. عنوان کلاس‌آرگومان‌های رویداد باید دارای پسوند EventArgs باشد.
مثال:
عنوان کلاس‌آرگومان:
AddEventArgs , EditEventArgs , DeleteEventArgs
عنوان رویداد:
Adding , Add , Added
تعریف یک EventHandler:
public delegate void <EventName>EventHandler  (object sender, <EventName>EventArgs e);
نکته: نیاز به تولید یک EventHandler مختص توسعه یک برنامه به‌ندرت ایجاد می‌شود. در اکثر موارد می‌توان با استفاده از کلاس جنریک <EventHandler<TEventArgs تمام احتیاجات خود را برطرف کرد.
تعریف یک رویداد:
public event EventHandler <AddEventArgs> Adding;

ج. اصول نام‌گذاری Attributeها
1. عنوان یک attribute باید اسم یا موصوف باشد.
2. در نام‌گذاری attributeها باید از روش Pascal Casing استفاده شود.
3. نباید از عناوین مخففی که رایج نیستند استفاده کرد.
4. از پیشوندهای زائد مثل A یا atr نباید استفاده شود.
5. نباید از کاراکترهایی به غیر از حروف در نام‌گذاری attributeها استفاده شود.
6. بهتر است در انتهای نام یک attribute از عبارت Attribute استفاده شود.
مثال:
DisplayNameAttribute , MessageTypeAttribute

چ. اصول نام‌گذاری Interfaceها
1. در ابتدای عنوان interface باید از حرف I استفاده شود.
2. نام باید اسم، موصوف یا صفتی باشد که interface را توصیف می‌کند.
به عنوان مثال:
IComponent  (اسم)
IConnectionProvider (موصوف)
ICloneable (صفت)
3. از روش Pascal Casing استفاده شود.
4. خودداری از بکاربردن عبارات مخفف غیررایج.
5. باید تنها از کاراکترهای حرفی در نام interface استفاده شود.
 
ح. اصول نام‌گذاری Enumerationها
1. استفاده از روش Pascal Casing
2. خودداری از کاربرد عبارات مخفف غیررایج
3. تنها از کاراکترهای حرفی در نام Enumretionها استفاده شود.
4. نباید از پسوند یا پیشوند Enum یا Flag استفاده شود.
5. اعضای یک Enum نیز باید با روش Pascal Casing نام‌گذاری شوند.
مثال:
public enum FileMode {
    Append,
    Read, …
}
6. درصورتی‌که enum موردنظر از نوع flag نیست باید عنوان آن مفرد باشد. 
7. درصورتی‌که enum موردنظر برای کاربرد flag طراحی شده باشد نام آن باید جمع باشد. مثال:
[Flag]
public enum KeyModifiers {
    Alt = 1, 
    Control = 2,
    Shift = 4
}
8. از به‌کاربردن پسوند و یا پیشوندهای اضافه در نام‌گذاری اعضای یک enum نیز پرهیز کنید. مثلا نام‌گذاری زیر نادرست است:
public enum OperationState {
    DoneState, 
    FaultState,
    RollbackState
}

خ. اصول نام‌گذاری متدها
1. نام متد باید فعل یا ترکیبی از فعل و اسم یا موصوف باشد.
2. باید از روش Pascal Casing استفاده شود.
3. خودداری از بکاربردن عبارات مخفف غیررایج و یا استفاده زیاد از اختصار
4. تنها از کاراکترهای حرفی برای نام متد استفاده شود.
مثال:
AddDays , Save , DeleteRow , BindData , Close , Open

د. اصول نام‌گذاری Propertyها
1. نام باید اسم، صفت یا موصوف باشد.
2. باید از روش Pascal Casing استفاده شود.
3. خودداری از بکاربردن عبارات مخفف غیررایج.
4. تنها از کاراکترهای حرفی برای نام‌گذاری پراپرتی استفاده شود.
مثال:
Radius , ReportType , DataSource , Mode , CurrentCenterId
5. از عبارت Get در ابتدای هیچ Propertyای استفاده نکنید.
6. نام خاصیت‌هایی که یک مجموعه برمی‌گرداند باید به صورت جمع باشد. عنوان این Propertyها نباید به‌صورت مفرد به همراه پسوند Collection یا List باشد. مثال:
public CenterCollection Centers { get; set; }
7. خواص Boolean را با عناوینی مثبت پیاده‌سازی کنید. مثلا به‌جای استفاده از CantRead از CanRead استفاده کنید. بهتر است این Propertyها پیشوندهایی چون Is, Can یا Has داشته باشند، البته تنها درصورتی‌که استفاده از چنین پیشوندهایی ارزش افزوده داشته و مفهوم آن را بهتر برساند. مثلا عنوان CanSeek مفهوم روشن‌تری نسبت به Seekable دارد. اما استفاده از Created خیلی بهتر از IsCreated است یا Enabled کاربرد به مراتب راحت‌تری از IsEnabled دارد.
برای تشخیص بهتر این موارد بهتر است از روش ifسنجی استفاده شود. به عنوان مثال
if (list.Contains(item))
if (regularExpression.Matches(text))
if (stream.CanSeek)
if (context.Created)
if (form.Enabled)
مفهوم درست‌تری نسبت به موارد زیر دارند:
if (list.IsContains(item))
if (regularExpression.Match(text))
if (stream.Seekable)
if (context.IsCreated)
if (form.IsEnabled)
8. بهتر است در موارد مناسب عنوان Property با نام نوعش برابر باشد. مثلا
public Color Color { get; set; }

ذ. اصول نام‌گذاری پارامترها
پارامتر درحالت کلی به آرگومان وروی تعریف شده برای یک متد گفته می‌شود.
1. حتما از یک نام توصیفی استفاده شود. از نام‌گذاری پارامترها براساس نوعشان به‌شدت پرهیز کنید.
2. از روش camel Casing استفاده شود.
3. تنها از کاراکترهای حرفی برای نام‌گذاری پارامترها استفاده شود.
مثال:
firstName , e , id , packageId , centerName , name
4. نکاتی برای نام‌گذاری پارامترهای Operator Oveloading:
- برای operatorهای دو پارامتری (binary operators) از عناوین left و right برای پارامترهای آن استفاده کنید:
public static MyType operator +(MyType left, MyType right)
public static bool operator ==(MyType left, MyType right)
- برای operatorهای تک‌پارامتری (unary operators) اگر برای پارامتر مورد استفاده هیچ عنوان توصیفی مناسبی پیدا نکردید حتما از عبارت value استفاده کنید:
public static MyType operator ++(MyType value)
- درصورتی‌که استفاده از عناوین توصیفی دارای ارزش افزوده بوده و خوانایی کد را بهتر می‌کند حتما از این نوع عناوین استفاده کنید:
public static MyType operator /(MyType dividend, MyType divisor)
- نباید از عبارات مخفف یا عناوینی با اندیس‌های عددی استفاده کنید:
public static MyType operator -(MyType d1, MyType d2) // incorrect!

ر. اصول نام‌گذاری متغیر (Variable)ها
- نام متغیر باید اسم، صفت یا موصوف باشد.
نام‌گذاری متغیرها باید با توجه به نوع آن انجام شود.
1. متغیرهای عمومی (public) و protected و Constantها
- استفاده از روش Pascal Casing
- تنها از کاراکترهای حرفی برای نام متغیر عمومی استفاده شود.
مثال:
Area , DataBinder , PublicCacheName
2. متغیرهای private (در سطح کلاس یا همان field)
- نام این نوع متغیر باید با یک "_" شروع شود.
- از روش camel Casing استفاده شود.
مثال:
_centersList
_firstName
_currentCenter
3. متغیرهای محلی در سطح متد
- باید از روش camel Casing استفاده شود.
- تنها از کاراکترهای حرفی استفاده شود.
مثال:
parameterType , packageOperationTypeId

ز. اصول نام‌گذاری کنترل‌های UI
1. نام باید اسم یا موصوف باشد.
2. استفاده از روش Hungarian !
3. عبارت مخفف معرفی‌کننده کنترل، باید به اندازه کافی برای تشخیص نوع آن مناسب باشد.
مثال:
lblName (Label)
txtHeader (TextBox)
btnSave (Button)

ژ. اصول نام‌گذاری Exceptionها
تمام موارد مربوط به نام‌گذاری کلاس‌ها باید در این مورد رعایت شود. 
1. باید از پسوند Exception در انتهای عنوان استفاده شود.
مثال:
ArgumentNullException , InvalidOperaionException

س. نام‌گذاری اسمبلی‌ها و DLLها
1. عناوینی که برای نام‌گذاری اسمبلی‌ها استفاده می‌شوند، باید نمایش‌دهنده محتوای کلی آن باشند. مثل:
System.Data
2. از روش زیر برای نام‌گذاری اسمبلی‌ها استفاده شود:
<Company>.<Component>.dll
<Company>.<Project|Product|Technology>.<Component>.dll
مثل:
Microsoft.CSharp.dll , Kara.CSS.Manager.dll

ش. نام‌گذاری پارامترهای نوع (Generic (type parameter
1. از حرف T برای پارامترهای تک‌حرفی استفاده کنید. مثل:
public int IComparer<T> {…}
public delegate bool Predicate<T> (T item)
2. تمامی پارامترهای جنریک را با عناوینی توصیفی و مناسب که مفهوم و کاربرد آنرا برساند نام‌گذاری کنید، مگر آنکه یافتن چنین عباراتی ارزش افزوده‌ای در روشن‌تر کردن کد نداشته باشد. مثال:
public int ISessionChannel<TSession> {…}
public delegate TOutput Converter<TInput, TOutput> (TInput from)
public class Nullable<T> {…}
public class List<T> {…}
3. در ابتدای عناوین توصیفی حتما از حرف T استفاده کنید.
4. بهتر است تا به‌صورتی روشن نوع قید قرار داده شده بر روی پارامتری خاص را در نام آن پارامتر نمایش دهید. مثلا اگر قید ISession را برای پارامتری قرار دادید بهتر است نام آن پارامتر را TSession درنظر بگیرید.
 
ص. نام‌گذاری کلید Resourceها
به دلیل شباهت ساختاری که میان کلیدهای resource و propertyها وجود دارد قواعد نام‌گذاری propertyها در اینجا نیز معتبر هستند.
1. از روش نام‌گذاری Pascal Casing برای کلیدهای resource استفاده کنید.
2. از عناوین توصیفی برای این کلیدها استفاده کنید. سعی کنید تا حد امکان به هیچ وجه از عناوین کوتاه و یا مخففی که مفهوم را به‌صورت ناکامل می‌رساند استفاده نکنید. درواقع سعی کنید که خوانایی بیشتر کد را فدای فضای بیشتر نکنید.
3. از کلیدواژه‌های CLR و یا زبان مورداستفاده برای برنامه‌نویسی در نام‌گذاری این کلیدها استفاده نکنید.
4. تنها از حروف و اعداد و _ در نام‌گذاری این کلیدها استفاده کنید.
5. سعی کنید از عناوین توصیفی همانند زیر برای پیام‌های مناسب خطاها جهت نمایش به کاربر برای کلیدهای مربوطه استفاده کنید. درواقع نام کلید باید ترکیبی از نام نوع خطا و یک آی‌دی مشخص‌کننده پیغام مربوطه باشد:
ArgumentExceptionIllegalCharacters
ArgumentExceptionInvalidName
ArgumentExceptionFileNotFound
 
نکاتی درمورد کلمات مرکب
کلمات مرکب به کلماتی گفته می‌شود که در آن از بیش از یک کلمه با مفهوم مستقل استفاده شده باشد. مثل Callback یا FileName. 
باید توجه داشت که با تمام کلمات موجود در یک کلمه مرکب نباید همانند یک کلمه مستقل رفتار کرد و حرف اول آن را در روش‌های نام‌گذاری موجود به‌صورت بزرگ نوشت. کلمات مرکبی وجود دارند که به آن‌ها closed-form گفته می‌شود. این کلمات مرکب با اینکه از 2 یا چند کلمه دارای مفهوم مستقل تشکیل شده‌اند اما به‌خودی‌خود دارای مفهوم جداگانه و مستقلی هستند. برای تشخیص این کلمات می‌توان به فرهنگ لغت مراجعه کرد (و یا به‌سادگی از نرم‌افزار Microsoft Word استفاده کرد) و دریافت که آیا کلمه مرکب موردنظر آیا مفهوم مستقلی برای خود دارد، یعنی درواقع آیا عبارتی closed-form است. با کلمات مرکب از نوع 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. این کلمات باید همان‌طور که در اینجا نشان داده شده‌اند استفاده شوند.
 
نکاتی درباره عبارات مخفف
1. عبارات مخفف (Acronym) با خلاصه‌سازی کلمات (Abbreviation) فرق دارند. یک عبارت مخفف شامل حروف اول یک عبارت طولانی یا معروف است، درصورتی‌که خلاصه‌سازی یک عبارت یا کلمه از حذف بخشی از آن به‌دست می‌آید. تا آنجاکه امکان دارد از خلاصه‌سازی عبارات نباید استفاده شود. هم‌چنین استفاده از عبارات مخفف غیررایج توصیه نمی‌شود.
مثال: IO و UI
2. براساس تعریف، یک مخفف حداقل باید 2 حرف داشته باشد. نحوه برخورد با مخفف‌های دارای بیشتر از 2 حرف با مخفف‌های دارای 2 حرف باهم متفاوت است. با مخفف‌های دارای 2 حرف همانند کلمه‌ای یک حرفی! برخورد می‌شود، درصورتی‌که با سایر مخفف‌ها همانند یک کلمه کامل چندحرفی برخورد می‌شود. به‌عنوان مثال IOStream برای روش PascalCasing و ioStream برای روش camelCasing استفاده می‌شود. هم‌چنین از HtmlBody و htmlBody به‌ترتیب برای روش‌های Pascal و camel استفاده می‌شود.
3. هیچ‌کدام از حروف یک عبارت مخفف در ابتدای یک واژه نام‌گذاری‌شده به روش camelCasing به‌صورت بزرگ نوشته نمی‌شود!
نکته: موارد زیادی را می‌توان یافت که در ابتدا به‌نظر می‌رسد برای پیاده‌سازی آنها باید قوانین فوق را نقض کرد. این موارد شامل استفاده از کتابخانه‌های سایر پلتفرم‌ها (مثل MFC, HTML و غیره)، جلوگیری از مشکلات جغرافیایی! (مثلا در مورد نام کشورها یا سایر موقعیت‌های جغرافیایی)، احترام به نام افراد درگذشته، و مواردی از این دست می‌شود. اما در بیشتر قریب به اتفاق این موارد هم می‌توان بدون تقض قوانین فوق اقدام به نام‌گذاری اشیا کرد، بدون اینکه با تغییر عبارت اصلی (که موجب تطابق با این قوانین می‌شود) لطمه‌ای به مفهوم آن بزند. البته تنها موردی که به‌نظر می‌رسد می‌تواند قوانین فوق را نقض کند نام‌های تجاری هستند. البته استفاده از نام‌های تجاری توصیه نمی‌شود، چون این نام‌ها سریع‌تر از محتوای کتابخانه‌های برنامه‌نویسان تغییر می‌کنند!
نکته: برای درک بهتر قانون "عدم استفاده از عبارات مخففی که رایج نیستند" مثالی از زبان توسعه دهندگان دات‌نت‌فریمورک ذکر می‌شود. در کلاس Color متد زیر با Overloadهای مختلف در دسترس است:
public class Color {
    …
    public static Color FromArgb(…)
    { … }
}
همان‌طور که مشاهده می‌شود برای رعایت قوانین فوق به‌جای استفاده از ARGB از عبارت Argb استفاده شده است. اما این نحوه استفاده موجب شده تا این سوال به‌ظاهر خنده‌دار اما درست پیش‌آید:
"چطور می‌شود در این کلاس رنگی را از ARGB تبدل کرد؟ هرچه که من میبینم فقط تبدیل از طریق (Argb) آرگومان b است!"
حال در این نقطه به‌نظر می‌رسد که در اینجا باید قوانین فوق را نقض کرد و از عنوان FromARGB که مفهوم درست را می‌رساند استفاده کرد. اما با کمی دقت متوجه می‌شویم که این قوانین در ابتدا نیز با پیاده‌سازی نشان داده شده در قطعه کد بالا نقض شده‌اند! همه می‌دانیم که عبارت RGB مخفف معروفی برای عبارت Red Green Blue است. اما استفاده از ARGB برای افزودن کلمه Alpha به ابتدای عبارت مذکور چندان رایج نیست. پس استفاده از مخفف Argb از همان ابتدا اشتباه به‌نظر می‌رسد. بنابراین راه‌حل بهتر می‌تواند استفاده از عنوان FromAlphaRgb باشد که هم قوانین فوق را نقض نکرده و هم مفهوم را بهتر می‌رساند.
 
دیگر نکات
1. قراردادهای اشاره شده در این سند حاصل کار شبانه روزی تعداد بسیاری از برنامه نویسان در سرتاسر جهان در پروژه‌های بزرگ بوده است. این اصول کلی تنها برای توسعه آسان‌تر و سریع‌تر پروژه‌های بزرگ تعیین شده‌اند و همان‌طور که روشن است تنها ازطریق تجربه دست‌یافتنی هستند. بنابراین چه بهتر است که در این راه از تجارب بزرگان این عرصه بیشترین بهره برده شود.
2. هم‌چنین توجه داشته باشید که بیشتر قراردادهای اشاره شده در این سند از راهنمای نام‌گذاری تیم توسعه BCL دات‌نت‌فریمورک گرفته شده است. این تیم طبق اعتراف خودشان زمان بسیار زیادی را برای نام‌گذاری اشیا صرف کرده‌اند و توصیه کرده‌اند که دیگران نیز برای نام‌گذاری، زمان مناسب و کافی را در توسعه پروژه‌ها درنظر بگیرند.
 
نظرات مطالب
فرم‌های مبتنی بر قالب‌ها در Angular - قسمت چهارم - اعتبارسنجی ورودی‌ها
در قسمت «بهبود اعتبارسنجی drop down» بنده قبلا در Angular 1.X برای این نوع اعتبار سنجی دایرکتیوی طراحی کرده بودم. این دایرکتیو لیست مقادیر غیر مجاز را دریافت میکرد و در صورتی که المنت یکی از این مقادیر را دریافت میکرد فرم invalid میشد. کدهای Angular 1.x به شکل زیر:
(function (app) {
    'use strict';

    function blackList() {
        return {
            require: 'ngModel',
            link: function (scope, elem, attr, ngModel) {
                var blacklist = attr.blackList.split(',');

                ngModel.$validators.blackList = function (modelValue) {
                    if (modelValue == undefined)
                        return 0;
                    var valid = blacklist.indexOf(modelValue.toString()) === -1;
                    return valid;
                };
            }
        };
    };

    app.directive("blackList", blackList);
})(angular.module('core'));
پس از برسی اینکه آیا در Angular نیز می‌توانیم دایرکتیوهایی به این صورت داشته باشیم، به این نتیجه رسیدم که بله خوشبختانه در Angular نیز میتوان اعتبار سنجی‌های سفارشی ساخت.
برای همین یک ماژول Angular برای اعتبار سنجی در Angular در صفحه گیت‌هاب خودم ایجاد کردم که فعلا تنها داری یک دایرکتیو برای اعتبار سنجی مقادیر غیر مجاز است. لطفا دوستان در صورت همکاری به این لینک مراجعه کنند.
بعد از اضافه کردن این ماژول طبق راهنما، برای قطعه کد موجود در «بهبود اعتبارسنجی drop down» از تگهای زیر می‌توان استفاده کرد.
<div [class.has-error]="blackList">
    <label>Primary Language</label>
    <select name="primaryLanguage" ngModel blackList='default' #primaryLanguage="ngModel">
          <option value="default">Select a Language...</option>
          <option *ngFor="let lang of languages">
            {{ lang }}
          </option>
      </select>
      <small [hidden]="primaryLanguage.valid">
        Not Valid
      </small>
  </div>
در این حالت بخاطر وجود دایرکتیو blackList با مقدار 'default' در صورتی که مقدار drop down با مقدار default انتخاب شده باشد فرم invalid خواهد بود و عبارت Not Valid نمایش داده خواهد شد.
پ.ن: این کد در عرض زمان خیلی کوتاهی آماده شد و منتشر شده است و احتمالا هنوز نیاز به اصلاح دارد.
مطالب
آشنایی با مفاهیم شیء گرایی در جاوا اسکریپت #1
با توجه به فراگیر شدن استفاده از جاوا اسکریپت و بخصوص مبحث شیء گرایی، تصمیم گرفتم طی سلسله مقالاتی با مباحث شیء گرایی در این زبان بیشتر آشنا شویم. جاوا اسکریپت یک زبان مبتنی بر شیء است و نه شیءگرا و خصوصیات زبان‌های شیء گرا، به طور کامل در آن پیاده سازی نمی‌گردد.
لازم به ذکر است که انواع داده‌ای در جاوا اسکریپت شامل 2 نوع می‌باشند:
1- نوع داده اولیه (Primitive) که شامل Boolean ، Number و Strings می‌باشند.
2- نوع داده Object که طبق تعریف هر Object مجموعه‌ای از خواص و متدها است.
نوع داده‌ای اولیه، از نوع Value Type و نوع داده ای Object، از نوع Refrence Type می‌باشد.

برای تعریف یک شیء (Object) در جاوا اسکریپت، 3 راه وجود دارد:
1 - تعریف و ایجاد یک نمونه مستقیم از یک شیء ( direct instance of an object )
2 – استفاده از function برای تعریف و سپس نمونه سازی از یک شیء ( Object Constructor )
3 – استفاده از متد Object.Create

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

مثال اول : (استفاده از new )
<script type=”text/javascript”>
 var person = new Object();
  person.firstname = “John”;
  person.lastname = “Doe”;
  person.age = 50;
  person.eyecolor = “blue”;
  document.write(person.firstname + “ is “ + person.age + “ years old.”);
</script>

result : John is 50 years old.
در این مورد، ابتدا یک شیء پایه ایجاد می‌گردد و خواص مورد نظر برایش تعریف می‌گردد و با استفاده از اسم شیء به این خواص دسترسی داریم.

مثال دوم (استفاده از literal notation )

<script type=”text/javascript”>
var obj = {
   var1: “text1”,
   var2: 5,
   Method: function ()
   {
     alert(this.var1);
   }
  };
  obj.Method();
</script>

 Result : text1
در این مورد با استفاده از کلمه کلیدی var یک شیء تعریف می‌شود و در داخل {}  کلیه خواص و متدهای این شیء تعریف می‌گردد. این روش برای تعریف اشیاء در جاوا اسکریپت بسیار متداول است.
هر دو مثالهای 1 و 2 در روش اول برای ایجاد اشیاء بکار میروند. امکان گسترش دادن اشیاء در این روش و اضافه کردن خواص و متد در آینده نیز وجود دارد. بعنوان مثال می‌توان نوشت :
 Obj.var3 = “text3”;
در این‌حال، خاصیت سومی به مجموع خواص شی Obj اضافه می‌گردد.
حال در این مثال اگر مقدار شی obj را برابر یک شیء دیگر قرار دهیم به نحو زیر :
   var newobj = obj;
  newobj.var1 = "other text";
  alert(obj.var1);// other text
  alert(newobj.var1);// other text
و برای اینکه بتوان از امکانات زبانهای شیء گرا در این زبان استفاده کرد، بایستی الگویی را تعریف کنیم و سپس از روی این الگو، اشیا مورد نظر را پیاده سازی نمائیم.
می‌بینیم که مقدار هر دو متغیر در خروجی یکسان می‌باشد و این موضوع با ماهیت شیء گرایی که در آن همه‌ی اشیایی که از روی یک الگو نمونه سازی می‌گردند مشخصه‌هایی یکسان، ولی مقادیر متفاوتی دارند، متفاوت است. البته این موضوع از آنجا ناشی می‌گردد که اشیاء ایجاد شده در جاوا اسکریپت ذاتا type refrence هستند و به همین منظور برای پیاده سازی الگویی (کلاسی) که بتوان رفتار شیء گرایی را از آن انتظار داشت از روش زیر استفاده میکنیم. برای درک بهتر اسم این الگو را کلاس مینامیم که در روش دوم به آن اشاره میکنیم.

روش دوم :

 <script type=”text/javascript”>
  function Person(firstname, lastname, age, eyecolor)
  {
     this.firstname = firstname;
     this.lastname = lastname;
     this.age = age;
     this.eyecolor = eyecolor;
  }

   var myFather = new Person("John", "Doe", 50, "blue");
  document.write(myFather.firstname + " is " + myFather.age + " years old.");
  result : John is 50 years old.

   var myMother=new person("Sally","Rally",48,"green");
   document.write(myMother.firstname + " is " + myFather.age + " years old.");
   result : Sally is 48 years old.
  </script>
یا به شکل زیر :

 var Person = function (firstname, lastname, age, eyecolor)
  {
     this.firstname = firstname;
     this.lastname = lastname;
     this.age = age;
     this.eyecolor = eyecolor;
  }

  var myFather = new Person("John", "Doe", 50, "blue");
  document.write(myFather.firstname + " is " + myFather.age + " years old.");
   result : John is 50 years old.

   var myMother=new person("Sally","Rally",48,"green");
   document.write(myMother.firstname + " is " + myFather.age + " years old.");
   result : Sally is 48 years old.
به این روش Object Constructor یا سازنده اشیاء گفته می‌شود.
در اینجا با استفاده از کلمه کلیدی function و در داخل {} کلیه خواص و متدهای لازم را به شیء مورد نظر اضافه می‌کنیم. استفاده از کلمه this در داخل function به این معنی است که هر کدام از نمونه‌های object مورد نظر، مقادیر متفاوتی خواهند داشت .

یک مثال دیگر :
 
<script type="text/javascript">
   function cat(name) {
      this.name = name;
      this.talk = function() {
      alert( this.name + " say meeow!" )
   }
 }

cat1 = new cat("felix")
cat1.talk() //alerts "felix says meeow!"
cat2 = new cat("ginger")
cat2.talk() //alerts "ginger says meeow!"
</Script>
در اینجا می‌بینیم که به ازای هر نمونه از اشیایی که با function می‌سازیم، خروجی متفاوتی تولید می‌گردد که همان ماهیت شیء گرایی است.


روش سوم :استفاده از متد Object.Create
 
 var myObjectLiteral = {
    property1: "one",
    property2: "two",
    method1: function() {
       alert("Hello world!");
}}
var myChild = Object.create(myObjectLiteral);
myChild.method1(); // will alert "Hello world!"
در این روش با استفاده از متد Object.Create و استفاده از یک شیء که از قبل ایجاد شده، یک شیء جدید ایجاد می‌شود.
حال برای اضافه کردن متدها و خاصیت‌هایی به کلاس جاوا اسکریپتی مورد نظر، به طوریکه همه‌ی نمونه‌هایی که از این کلاس ایجاد می‌شوند بتوانند به این متدها و خاصیت‌ها دسترسی داشته باشند، از مفهومی به اسم prototype استفاده می‌کنیم. برای مثال کلاس زیر را در نظر بگیرید:
این کلاس یک سیستم ساده امتحانی (quiz ) را پیاده می‌کند که در آن اطلاعات شخص که شامل نام و ایمیل می‌باشد گرفته شده و سه تابع، شامل ذخیره نمرات، تغییر ایمیل و نمایش اطلاعات شخص به همراه نمرات نیز به آن اضافه می‌شود.
 function User (theName, theEmail) {
    this.name = theName;
    this.email = theEmail;
    this.quizScores = [];
    this.currentScore = 0;
}
حال برای اضافه نمودن متدهای مختلف به این کلاس داریم :

 User.prototype = {
  saveScore:function (theScoreToAdd)  {
   this.quizScores.push(theScoreToAdd)
  },
  showNameAndScores:function ()  {
    var scores = this.quizScores.length > 0 ? this.quizScores.join(",") : "No Scores Yet";
    return this.name + " Scores: " + scores;
  },
  changeEmail:function (newEmail)  {
    this.email = newEmail;
    return "New Email Saved: " + this.email;
  }
}
و سپس برای استفاده از آن و گرفتن خروجی نمونه داریم :
 // A User
  firstUser = new User("Richard", "Richard@examnple.com");
  firstUser.changeEmail("RichardB@examnple.com");
  firstUser.saveScore(15);
  firstUser.saveScore(10);
  document.write(firstUser.showNameAndScores()); //Richard Scores: 15,10
  document.write('<br/>');
  // Another User
  secondUser = new User("Peter", "Peter@examnple.com");
  secondUser.saveScore(18);
  document.write(secondUser.showNameAndScores()); //Peter Scores: 18
در نتیجه تمام نمونه‌های کلاس User می‌توانند به این متدها دسترسی داشته باشند و به این صورت مفهوم Encapsulation  نیز پیاده می‌گردد.


وراثت (Inheritance) در جاوا اسکریپت :

در بسیاری از مواقع لازم است عملکردی (Functionality) که در یک کلاس تعریف می‌گردد، در کلاسهای دیگر نیز در دسترس باشد. بدین منظور از مفهوم وراثت استفاده می‌شود. در نتیجه کلاس‌ها می‌توانند از توابع خود و همچنین توابعی که کلاسهای والد در اختیار آنها می‌گذارند استفاده کنند. برای این منظور چندین راه حل توسط توسعه دهندگان ایجاد شده است که در ادامه به چند نمونه از آنها اشاره می‌کنیم.
ساده‌ترین حالت ممکن از الگویی شبیه زیر است:
   
 <script type="text/javascript">
function Base()
  {
     this.color = "blue";
  }
  function Sub()
  {
  }
  Sub.prototype = new Base();
  Sub.prototype.showColor = function ()
  {
     alert(this.color);
  }
  var instance = new Sub();
  instance.showColor(); //"blue"
</Script>
در کد بالا ابتدا یک function (class) به نام Base که حاوی یک خصوصیت به نام color  می‌باشد، تعریف شده و سپس یک کلاس دیگر بنام sub تعریف می‌کنیم که قرار است خصوصیات و متدهای کلاس Base را به ارث ببرد و سپس از طریق خصوصیت prototype کلاس Sub، که نمونه‌ای از کلاس Base را به آن نسبت می‌دهیم باعث می‌شود خواص و متدهای کلاس Base توسط کلاس Sub قابل دسترسی باشد. در ادامه متد showColor را به کلاس Sub اضافه می‌کنیم و توسط آن به خصوصیت color در این کلاس دسترسی پیدا میکنیم.
راه حل دیگری نیز برای اینکار وجود دارد که الگویی است بنام Parasitic Combination :
در این الگو براحتی و با استفاده از متد Object.create که در بالا توضیح داده شد، هر کلاسی که ایجاد میکنیم، با انتساب آن به یک شیء جدید، کلیه خواص و متدهای آن نیز توسط شیء جدید قابل استفاده میشود.
 <script language="javascript" type="text/javascript">
if (typeof Object.create !== 'function') {
Object.create = function (o) {
ایجاد یک کلاس خالی که قرار است خواص کلاس دریافتی توسط آرگومان کلاس پایه را به ارث ببرد//
  function F() {
}
با ارث برده شود F  باعث میشویم کلیه خواص و متدهای دریافتی توسط Prototype  توسط خصوصیت  F با انتساب آرگومان دریافتی که یک شی است به کلاس
  F.prototype = o;
   return new F(); 
  };
}

var cars = {
type: "sedan",
wheels: 4
  };
  // We want to inherit from the cars object, so we do:
  var toyota = Object.create(cars);
// now toyota inherits the properties from cars
  document.write(toyota.type);
</script>
output :sedan
در قسمتهای دیگر به مباحثی همچون Override و CallBaseMethod‌ها خواهیم پرداخت.

برای مطالعه بیشتر :
http://eloquentjavascript.net/chapter8.html
http://phrogz.net/JS/classes/OOPinJS2.html
اشتراک‌ها
کتابخانه سی‌شارپی برای کار با اثر انگشت
چنانچه در کارهای خود نیازمند تشخیص اثر انگشت هستید (مثلا برای تشخیص هویت به هنگام ورود به برنامه) می‌توانید از این کتابخانه استفاده کنید.


کتابخانه سی‌شارپی برای کار با اثر انگشت