Enterprise Go: كيفية كتابة كود لا تخجل من عرضه على CTO

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

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

ابدأ الدورة

Go في الأعمال الكبيرة: لماذا لم يعد مجرد "لغة للخدمات المصغرة"

\n\n

عندما تسمع "Enterprise Go"، ما الذي يتبادر إلى ذهنك؟ لوائح الشركات المملة؟ مراجعات كود لا نهائية؟ أم ربما شعور بأن Go مخصص فقط للشركات الناشئة و DevOps؟

\n\n

في الواقع، Go في المؤسسات هو مستوى مختلف تمامًا من الانضباط والثقافة الهندسية. في الشركات الكبرى (Uber، Dropbox، Salesforce، Twitch) لا يكتبون باستخدام Go مجرد خدمات مصغرة، بل منصات كاملة تعالج ملايين الطلبات في الثانية. وهنا "مجرد أنه يعمل" ليس كافيًا.

\n\n

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

\n\n

1. الهندسة المعمارية: لا تكرر خطأ "المونوليث في الخدمات المصغرة"

\n\n

المشكلة الأكثر شيوعًا التي أراها في مشاريع Go على مستوى المؤسسات هي محاولة نقل بنية Java-style إلى Go. النتيجة: مئات الواجهات غير الضرورية وطبقات تجريدية تبطئ التطوير فقط.

\n\n

قاعدة "الحزمة حسب الميزة، وليس حسب الطبقة"

\n\n

بدلاً من إنشاء مجلدات /models، /handlers، /services — قم بالتجميع حسب مجالات الأعمال:

\n\n
myapp/\n├── cmd/\n│   └── server/\n│       └── main.go\n├── internal/\n│   ├── user/          # كل ما يتعلق بالمستخدمين\n│   │   ├── handler.go\n│   │   ├── service.go\n│   │   ├── repository.go\n│   │   └── user.go    # نموذج البيانات\n│   ├── payment/       # كل ما يتعلق بالمدفوعات\n│   │   ├── handler.go\n│   │   ├── service.go\n│   │   ├── gateway.go\n│   │   └── payment.go\n│   └── pkg/           # الأدوات المساعدة العامة\n└── go.mod
\n\n

هذا النهج هو أحد أفضل ممارسات Go للمؤسسات. إنه يقلل من الاقتران ويجعل الكود قابلاً للتنبؤ. عندما يفتح مطور جديد المشروع، يرى على الفور منطق الأعمال، وليس طبقات التجريد.

\n\n

الواجهات: استقبل الواجهات، وأعد الهياكل

\n\n

هذه نصيحة كلاسيكية من مجتمع Go، لكنها حاسمة في المؤسسات. يجب أن تكون الواجهات صغيرة (1-2 طريقة) ويتم تعريفها حيث تُستخدم، وليس حيث تُنفذ.

\n\n
// سيء: الواجهة محددة بجانب التنفيذ\npackage user\n\ntype UserRepository interface {\n    FindByID(id string) (*User, error)\n    Save(user *User) error\n}\n\ntype postgresRepo struct { ... }\n\n// جيد: الواجهة حيثما تكون مطلوبة\npackage user\n\ntype Storage interface {\n    Get(id string) (*User, error)\n    Put(user *User) error\n}\n\ntype service struct {\n    db Storage\n}\n\nfunc NewService(db Storage) *service {\n    return &service{db: db}\n}
\n\n

لماذا هذا مهم؟ لأنه في المؤسسات، غالبًا ما تغير الأنظمة الخلفية (PostgreSQL -> CockroachDB، Redis -> KeyDB). الواجهات المحددة من جانب المستهلك تسمح بذلك دون ألم.

\n\n

2. معالجة الأخطاء: توقف عن تجاهل _

\n\n

لا توجد استثناءات في Go، وهذا رائع. لكن في مشاريع المؤسسات، الأخطاء ليست مجرد if err != nil. إنها ثقافة كاملة.

\n\n

التغليف أم لا؟

\n\n

استخدم fmt.Errorf مع %w لإنشاء سلاسل من الأخطاء. هذا يسمح بالحفاظ على مكدس الاستدعاءات ويبسط التصحيح.

\n\n
func (s *service) ProcessOrder(ctx context.Context, orderID string) error {\n    order, err := s.orderRepo.Get(ctx, orderID)\n    if err != nil {\n        return fmt.Errorf("getting order %s: %w", orderID, err)\n    }\n\n    if err := s.paymentGateway.Charge(ctx, order.Amount); err != nil {\n        return fmt.Errorf("charging for order %s: %w", orderID, err)\n    }\n\n    return nil\n}
\n\n

على المستوى الأعلى (في handler/middleware) استخدم errors.Is() و errors.As() للتحقق من أنواع الأخطاء:

\n\n
if errors.Is(err, ErrNotFo                

المدونات

توصيات الكتب