1. Comprehension of Naming Conventions

تعتبر اتفاقيات التسمية أمرًا حاسمًا في تطوير البرمجيات، حيث توفر إطارًا لتسمية المتغيرات والدوال والمعرفات الأخرى بطريقة متسقة وواضحة. في لغة البرمجة Go (المعروفة أيضًا باسم Golang)، يسهل اتباع اتفاقيات التسمية المُعتَمَدَة فقط فهم وصيانة رمزك بشكل أفضل، كما يتيح للآخرين (والنسخة المستقبلية لنفسك) فهم والتعاون على قاعدة الرموز الخاصة بك بأقل احتكاك.

1.1. لماذا التسمية مهمة

في أي لغة برمجة، يمكن أن يؤثر الشكل الذي تسمي به المعرفات الخاصة بك بشكل كبير على فهم رمزك وقابليته للصيانة. في Go، الذي يؤكد على البساطة والوضوح، فإن التسمية السليمة أمر أكثر أهمية. الأسماء التي توضح بوضوح الغرض من المتغير أو الدالة تقلل من الحاجة إلى تعليقات إضافية وتجعل الرمز يوثق نفسه بنفسه. وهذا أمر حاسم للحفاظ على قاعدة رموز على مر الزمن وتمكين التعاون السلس بين الفريق.

1.2. القواعد العامة للتسمية

تعتبر قواعد التسمية في Go بسيطة ولكنها قوية:

  • استخدام أسماء قصيرة وموجزة: يشجع Go على استخدام الأسماء القصيرة، خصوصًا للمتغيرات ذات النطاق الصغير. على سبيل المثال، يمكن استخدام i لعداد الحلقة، ولكن يمكن استخدام index أو counter إذا كان هناك حاجة لمزيد من الوضوح.

  • CamelCase للأسماء متعددة الكلمات: عندما يتكون الاسم من عدة كلمات، استخدم تعبير CamelCase. يجب أن تبدأ الأسماء القابلة للاستخدام (تلك التي يجب أن تكون قابلة للوصول خارج الحزمة) بحرف كبير (MyFunction)، بينما يجب أن تبدأ الأسماء الداخلية بحرف صغير (myFunction).

  • استخدام أسماء ذات معنى: يجب أن تكون الأسماء وصفية بما يكفي لنقل الغرض أو الاستخدام الخاص بها دون أن تكون طويلة بشكل مفرط. على سبيل المثال، يُفضل CalculateNetIncome على CNI.

  • تجنب استخدام الشرطات السفلية: على عكس بعض اللغات، تجنبت اتفاقية Go استخدام الشرطات السفلية في الأسماء. بدلاً من record_count، يجب استخدام recordCount.

  • يجب أن تكون الاختصارات متسقة: عند استخدام الاختصارات في الأسماء، يجب الاحتفاظ بها في حالة متسقة. للأسماء التي تكون قابلة للاستخدام، استخدم حروف كبيرة (HTTPServer)، وللأسماء الداخلية، يُعد استخدام الحروف الصغيرة (httpServer) ممارسة قياسية.

  • يجب أن تكون أسماء الحزم بسيطة: يُبقى أسماء الحزم في Go بسيطة وبحروف صغيرة، دون شرطات سفلية أو تبدء بحروف كبيرة مختلطة. يجب أن تكون كلمة واحدة تمثل بوضوح الغرض من الحزمة (net, os, json).

  • تسمية المتغيرات استنادًا إلى النوع: بالنسبة للمتغيرات التي تمثل حالات من الهياكل، فمن الشائع استخدام اسم الهيكل بحروف صغيرة كاسم المتغير (var user User).

فيما يلي مثال على رمز Go مع تعليقات توضح اختيارات التسمية:

package main

import "fmt"

type User struct {
    FirstName string
    LastName  string
    Age       int
}

func main() {
    var currentUser User // استخدام اسم الهيكل بحروف صغيرة كاسم متغير.
    currentUser.FirstName = "John"
    currentUser.LastName = "Doe"
    currentUser.Age = 30

    fmt.Println(formatUserDetails(currentUser))
}

// formatUserDetails يأخذ هيكل المستخدم كإدخال ويعيد سلسلة مُقَنَّنَة.
// يبدأ اسم الدالة بحرف صغير لأنها غير قابلة للصدور (خاصة).
func formatUserDetails(u User) string {
    return fmt.Sprintf("الاسم: %s %s، العمر: %d", u.FirstName, u.LastName, u.Age)
}

الالتزام بهذه الاتفاقيات التسمية سيحسن بشكل كبير جودة رموزك في Go من خلال جعلها أكثر قراءة وصيانة.

2. المعرفات في Go

عندما تبدأ رحلتك مع Go، من الأمور الضرورية فهم دور المعرفات. المعرفات هي الأسماء التي تُسَمَّي بها مختلف العناصر في رمزك، مثل المتغيرات والدوال والثوابت. اختيار أسماء ذات معنى ومتسقة يساعد على جعل رمزك أكثر قراءة وصيانة.

2.1. اتفاقيات تسمية المتغيرات

في Go، يجب أن تبدأ أسماء المتغيرات بحرف أو شرطة سفلية، تليها أي مجموعة من الحروف والأرقام أو الشرطات السفلية. ومع ذلك، فإن البدء بشرطة سفلية غير مستحسن لأنها عادة ما تكون محجوزة لاستخدامات خاصة.

أفضل الممارسات:

  • استخدام أسماء قصيرة ووصفية.
  • البدء بحرف صغير لمتغيرات الحزمة.
  • استخدام تعبير CamelCase للأسماء متعددة الكلمات (على سبيل المثال، totalAmount).
  • بالنسبة للمتغيرات القابلة للصدور (يمكن الوصول إليها خارج الحزمة)، يجب البدء بحرف كبير.

مثال:

var userName string // متغير غير قابل للصدور
var UserAge int     // متغير قابل للصدور

توضح التعليقات في الرمز الفرق بين المتغيرات القابلة وغير القابلة للصدور.

2.2. اتفاقيات تسمية الدوال

الدوال في Go يتم تسميتها وفقًا لقواعد مماثلة للمتغيرات. يجب أن يعكس اسم الدالة غرضه، ويحدد نطاقه حالة الحرف الأول.

أفضل الممارسات:

  • استخدام أسماء واضحة تعكس غرض الدالة.
  • البدء بحرف صغير للدوال الداخلية.
  • استخدام PascalCase (البدء بحرف كبير) للدوال المصدرة.
  • الحفاظ على اختصار أسماء الدوال وفهمها.

مثال:

func calculateTotal(price int, quantity int) int { // دالة داخلية
    return price * quantity
}

func CalculateDiscount(totalPrice int) float64 { // دالة مصدرة
    return totalPrice * 0.1
}

التعليقات تشرح إمكانية الوصول إلى الدالة استنادًا إلى الحالة وتقدم بصفة موجزة نظرة عامة على غرضها.

2.3. اتفاقيات تسمية الثوابت

الثوابت هي قيم ثابتة لا يمكن تغييرها بمجرد تعريفها. في Go، يتم تعريف الثوابت باستخدام كلمة المفتاح const ويمكن أن تكون قيم الطابع، النص، البوليانية، أو الرقمية.

أفضل الممارسات:

  • استخدام أحرف كبيرة مع خطوط تحتية للفصل (على سبيل المثال، MAX_LIMIT).
  • بالنسبة للثوابت المعدودة، استخدام enumerator iota.
  • الثوابت المصدرة يجب أن تبدأ بحرف كبير.

مثال:

const MAX_RETRY_COUNT int = 3 // الثابت المصدر
type ByteSize float64
const (
    _           = iota // تجاهل القيمة الأولى عن طريق الاسناد إلى هوية فارغة
    KB ByteSize = 1 << (10 * iota)
    MB
    GB
    TB
)

يوضح المثال كيفية تعريف الثوابت البسيطة ومجموعة من الثوابت المرتبطة باستخدام iota لأحجام البايت.

3. اتفاقيات التسمية للأنواع

هذا الفصل يركز على المعايير لتسمية أنواع مختلفة مثل الهياكل والواجهات.

3.1. إرشادات تسمية الهياكل

نظرة عامة: الهياكل في Go تمثل أنواع بيانات مركبة تجمع بين المتغيرات. عند تسمية الهياكل، استخدم أسماء واضحة بـ PascalCase، والتي تبدأ بحرف كبير.

  • ممارسة جيدة: قم بتسمية الهياكل باستخدام أسماء أو عبارات اسمية تصف بشكل واضح ما يمثلونه. على سبيل المثال:
// جيد
type Employee struct {
    ID        int
    FirstName string
    LastName  string
    Position  string
}
  • تجنب: استخدام أسماء غامضة أو عامة لا توصف غرض الهيكل.
// تجنب
type Data struct {
    ID        int
    FirstName string
    LastName  string
    Position  string
}

3.2. إرشادات تسمية الواجهات

نظرة عامة: الواجهات في Go تحدد مجموعات الطرق ويتم تسميتها باستخدام أسماء واضحة تنتهي بـ 'er' إذا كان من المعقول.

  • ممارسة جيدة: قم بتسمية الواجهات استنادًا إلى السلوك الذي تجرده. عادة، إذا كانت الواجهة تحتوي على طريقة واحدة فقط، يجب أن يعكس الاسم فعل هذه الطريقة مع لاحقة '-er'.
// جيد
type Reader interface {
    Read(p []byte) (n int, err error)
}
  • تسمية مجموعات السلوك: إذا كانت الواجهة تمثل مجموعة من السلوكيات، اختر اسمًا يعكس بدقة غرضها دون اللاحقة 'er'.
// مثال على مجموعة من السلوكيات
type Filesystem interface {
    ReadFile(path string) ([]byte, error)
    WriteFile(path string, data []byte) error
}

4. حساسية الحالة والمعرفات المصدرة

4.1. المعرفات المصدرة مقابل المعرفات غير المصدرة

في Go، يتم تحديد رؤية معرف خارج حزمته الخاصة استنادًا إلى حالة حرفه الأول. المعرف الذي يبدأ بحرف كبير هو 'مصدر'، مما يعني أنه يمكن الوصول إليه من حزم أخرى. يشبه هذا الأمر النطاق العام في لغات البرمجة الأخرى. من ناحية أخرى، المعرّفات التي تبدأ بحروف صغيرة 'غير مصدرة' أو خاصة، ويمكن الوصول إليها فقط داخل حزمتها الخاصة.

مثال:

package geometry

// معرف مصدر
type Rectangle struct {
    Length, Width float64
}

// معرف غير مصدر
type point struct {
    x, y float64
}

في هذا المثال، Rectangle هو نوع مصدر لأنه يبدأ بحرف كبير ويمكن استخدامه من قبل الحزم الأخرى التي تستورد حزمة geometry. على الجانب الآخر، النوع point هو غير مصدر ويمكن استخدامه فقط داخل حزمة geometry.

4.2. أفضل الممارسات لتسميات المعرفات المصدرة

عند تسمية المعرفات المصدرة، من الضروري اتباع بعض أفضل الممارسات لضمان قراءة وفهم الرمز الخاص بك من قبل الآخرين:

  • الوضوح يتفوق على الإيجاز: اختر أسماء واضحة ووصفية عوضًا عن أسماء قصيرة ومبهمة. على سبيل المثال، يُفضل حساب_المساحة بدلاً من حساب_أ.
  • الاتساق: كن متسقًا في تقاليد التسمية في رمزك. إذا بدأت في تسمية الكيانات المماثلة بأنماط معينة، فتمسك بها.
  • تجنب الزيادة في الكلمات: لا تكرر أسماء الحزم في أسماء المعرفات. على سبيل المثال، استخدم مضلع.مستطيل بدلاً من مضلع.مستطيل_هندسي.
  • النظر في السياق: يجب أن تكون أسماء المعرفات منطقية في السياق الذي يتم فيه استخدامها. تجنب الأسماء التي قد تكون مضللة أو غامضة.
  • تعليقات الوثائق: استخدم التعليقات لوثائق المعرفات المصدرة، مشرحًا ما تفعله وكيف يجب استخدامها.

مثال:

package geometry

// CalculateArea تقوم بإعادة مساحة مستطيل.
func (r Rectangle) CalculateArea() float64 {
    return r.Length * r.Width
}

في هذا المثال، CalculateArea هي دالة مصدرة لها اسم واضح ووصفي تتضمن تعليقات وثائق تشرح الغرض منها.

5. تطبيق تقاليد التسميات في الممارسة

في هذا الفصل، سنغوص في تطبيق تقاليد التسميات في جو في سيناريوهات العالم الحقيقي. فهم والالتزام بهذه التقاليد أمر بالغ الأهمية حيث يضمن أن يكون رمزك اصطلاحيًا وأسهل قراءة وصيانة.

5.1. الأخطاء الشائعة وكيفية تجنبها

غالبًا ما يتم تقدير تسمية المتغيرات والدوال والمعرفات الأخرى بشكل كبير. تشمل الأخطاء الشائعة ما يلي:

  • استخدام أسماء عامة: أسماء مثل بيانات أو معلومات ليست وصفية ويمكن أن تؤدي إلى الارتباك.
  • أسماء طويلة جدًا: بينما الأسماء الوصفية جيدة، الأسماء الطويلة جدًا يمكن أن تكون مرهقة. ابحث عن توازن.
  • شرطات سفلية في معرفات متعددة الكلمات: يفضل في جو استخدام كاميل كيس لأسماء المتغيرات وباسكال كيس للدوال والأنواع المصدرة.
  • أنماط تسمية غير متسقة: الاتساق في تقاليد التسمية يساعد في فهم هيكل الرمز بسرعة.

نصائح لتجنب هذه الأخطاء:

  • استخدم أسماء موجزة ووصفية. على سبيل المثال، استخدم بيانات_المستخدم بدلاً من بيانات إذا كانت تحتوي على معلومات حول المستخدمين.
  • اتبع توجيهات جو بخصوص الاختصارات؛ حافظ عليها كأحرف كبيرة، مثل HTTPServer بدلاً من HttpServer.
  • بالنسبة للمتغيرات والثوابت على مستوى الحزم غير المصدرة، حافظ على أسماء مختصرة لأن نطاقها محدود.

5.2. إعادة التشكيل لأسماء أفضل

إعادة تشكيل الرمز لتحسين أسماء المعرفات يمكن أن يعزز قراءة الرمز بشكل كبير. إليك كيف يمكنك القيام بذلك بأمان:

  1. استخدام أسماء وصفية: أعد صياغة الأسماء لتصرح بوضوح بما تمثله أو تفعله. على سبيل المثال، أعد تسمية دالة من معالجة إلى معالجة_إدخال_المستخدم إذا كانت تقوم بذلك.
  2. الاستفادة من الأدوات: استخدم أدوات مثل gorename التي تسمح بإعادة التسمية بأمان عن طريق تحليل رمز جو بشكل دلالي بدلاً من نصي.
  3. مراجعة مع النظراء: في بعض الأحيان ما قد يبدو منطقيًا لك قد لا يكون واضحًا للآخرين. يمكن أن تساعد مراجعة النظراء في تحديد الأسماء المبهمة.
  4. تكرار التغذية الراجعة: بعد إجراء التغييرات، اجمع ملاحظات من مستخدمي رمز الرمز وكرر عملية التسمية إذا لزم الأمر.

من خلال اتباع هذه التقنيات، ستضمن أن تبقى قاعدة رمز جو الخاصة بك نظيفة وقابلة للقراءة والصيانة.