Clean Code على Go: مبادئ كتابة كود قابل للقراءة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كود نظيف في Go: مبادئ كتابة كود قابل للقراءة والصيانة



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



١. التسمية الصحيحة: أساس قابلية القراءة



في Go تنطبق القاعدة: كلما كان النطاق أصغر، كان الاسم أقصر. لكن هذا لا يعني استخدام متغيرات بحرف واحد في كل مكان. لنلقِ نظرة على الأمثلة.



سيء (كود غير قابل للقراءة):

func f(x int, y int) int {    z := x + y    return z}


جيد (كود نظيف):

func Sum(a int, b int) int {    result := a + b    return result}


قواعد التسمية الهامة في Go:

  • المتغيرات: استخدم camelCase (مثل userName و totalCount)
  • الدوال والأنواع المُصدَّرة (العامة): بحرف كبير — func CalculateTax()
  • غير المُصدَّرة (الخاصة): بحرف صغير — func parseInput()
  • الاختصارات: اكتبها بأحرف كبيرة (مثل HTTPHandler وليس HttpHandler)
  • تجنب الترميز المجري: لا تكتب strName أو intCount — النوع واضح بالفعل


٢. معالجة الأخطاء: صريحة وموجزة



Go لا تستخدم الاستثناءات — الأخطاء تُعاد كقيم. الكود النظيف يتطلب معالجة صريحة لكل خطأ. لا تتجاهلها!



سيء (تجاهل الخطأ):

file, _ := os.Open("data.txt")// الخطأ ضاع!


جيد (معالجة صريحة):

file, err := os.Open("data.txt")if err != nil {    log.Fatalf("فشل فتح الملف: %v", err)}defer file.Close()


نصائح إضافية:

  • تحقق دائمًا من err != nil مباشرة بعد استدعاء الدالة
  • استخدم defer لإغلاق الموارد
  • أنشئ أنواع أخطاء مخصصة باستخدام fmt.Errorf("سياق: %w", err)
  • لا تستخدم الذعر (panic) للأخطاء العادية — هذا موقف استثنائي


٣. الدوال: قصيرة وذات مسؤولية واحدة



مبدأ المسؤولية الواحدة (Single Responsibility Principle) ينطبق أيضًا على الدوال. كل دالة يجب أن تفعل شيئًا واحدًا فقط.



سيء (الدالة تفعل الكثير):

func ProcessUserData(userID int) (string, error) {    // ١. الاتصال بقاعدة البيانات    db, _ := sql.Open("postgres", "...")    // ٢. استعلام البيانات    row := db.QueryRow("SELECT name, email FROM users WHERE id = ?", userID)    // ٣. التنسيق    var name, email string    row.Scan(&name, &email)    result := fmt.Sprintf("الاسم: %s، البريد: %s", name, email)    // ٤. إرسال بريد إلكتروني (تأثير جانبي!)    sendEmail(email, "ترحيب")    return result, nil}


جيد (تقسيم إلى دوال صغيرة):

func GetUserName(db *sql.DB, userID int) (string, error) {    var name string    err := db.QueryRow("SELECT name FROM users WHERE id = ?", userID).Scan(&name)    return name, err}

func FormatUserInfo(name, email string) string { return fmt.Sprintf("الاسم: %s، البريد: %s", name, email)}

func ProcessUserData(db *sql.DB, userID int) (string, error) { name, err := GetUserName(db, userID) if err != nil { return "", fmt.Errorf("خطأ في الحصول على المستخدم: %w", err) } email, _ := getUserEmail(db, userID) /```

المدونات

توصيات الكتب