التصميم القائم على المجال في Go: كيف لا تغرق في طبقات التجريد

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

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

ابدأ الدورة

مقدمة: لماذا مشروع Go الخاص بك يحتاج إلى DDD؟

\n\n

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

\n\n

مشكلة التطوير الكلاسيكي بلغة Go هي أننا نفكر مبكراً جداً في قواعد البيانات و JSON، متناسين الشيء الرئيسي: منطق الأعمال. يأتي التصميم القائم على المجال (DDD) للمساعدة تحديداً عندما تريد إحلال النظام في الفوضى. ولكن كيف نطبق DDD على Go، إذا كانت اللغة لا تمنحنا الفئات والوراثة؟ دعنا نكتشف ذلك.

\n\n

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

\n\n

ما هو DDD ولماذا هو ضروري لمطور Go؟

\n\n

التصميم القائم على المجال ليس عن التقنيات. إنه عن اللغة. عن جعل الكود يتحدث لغة الأعمال. إذا كان مجال عملك هو متجر إلكتروني، فيجب أن يكون في الكود Order و Product و Cart، وليس DataTransferObject و EntityManager.

\n\n

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

\n\n

اللبنات الأساسية لـ DDD التي سننظر فيها:

\n
    \n
  • Entity (كيان) — كائن بمعرف فريد (مثل User).
  • \n
  • Value Object (كائن القيمة) — كائن غير قابل للتغيير يصف الخصائص (مثل Address).
  • \n
  • Aggregate (تجميع) — مجموعة من الكيانات تضمن الاتساق (مثل Order مع OrderItem).
  • \n
  • Repository (مستودع) — مجموعة من الكائنات تخفي تفاصيل التخزين.
  • \n
  • Domain Service (خدمة المجال) — عملية لا تتناسب مع كيان واحد.
  • \n
\n\n

الآن دعنا نترجم هذا إلى Go.

\n\n

هيكل المشروع: كيف لا تضيع في المجلدات

\n\n

الخبر الجيد: Go لا يفرض أي هيكل. الخبر السيئ: بدون هيكل ستغرق بسرعة. لـ DDD في Go أوصي بتنظيم الكود التالي:

\n\n
your-project/\n├── cmd/\n│   └── server/\n│       └── main.go\n├── internal/\n│   ├── domain/          # النواة النقية: الكيانات، القواعد\n│   │   ├── order.go\n│   │   ├── product.go\n│   │   └── errors.go\n│   ├── application/     # حالات الاستخدام / خدمات التطبيق\n│   │   ├── order_service.go\n│   │   └── product_service.go\n│   └── infrastructure/  # قواعد البيانات، واجهات برمجة التطبيقات الخارجية، معالجات HTTP\n│       ├── postgres/\n│       │   └── order_repository.go\n│       └── http/\n│           └── handler.go\n└── go.mod
\n\n

لاحظ: domain لا يستورد infrastructure. هذه هي القاعدة الذهبية لـ DDD — المجال لا يعرف شيئاً عن قواعد البيانات و HTTP. إنه يعيش في فراغ من الهياكل والواجهات النقية.

\n\n

كتابة المجال: Order و Value Objects

\n\n

لنبدأ بالنواة. لنفترض أننا نبني نظام إدارة طلبات. إليك كيف قد يبدو كيان Order:

\n\n
// internal/domain/order.go\npackage domain\n\nimport (\n    "errors"\n    "time"\n)\n\ntype OrderStatus string\n\nconst (\n    OrderStatusPending   OrderStatus = "pending"\n    OrderStatusConfirmed OrderStatus = "confirmed"\n    OrderStatusCancelled OrderStatus = "cancelled"\n)\n\ntype OrderID string\n\ntype Order struct {\n    ID         OrderID\n    CustomerID string\n    Items      []OrderItem\n    Status     OrderStatus\n    CreatedAt  time.Time\n    Upd                

المدونات

توصيات الكتب