مقدمة: ما هو المستودع الأحادي (monorepo) ولماذا هو ضروري في Java
في عالم تطوير Java، هناك نهجان رئيسيان لتخزين الكود: المستودع الأحادي (monorepo) والمستودع المتعدد (multirepo). المستودع الأحادي هو استراتيجية يتم فيها تخزين جميع قواعد كود المشروع (المكتبات، الخدمات، الأدوات، الإعدادات) في مستودع واحد. بالنسبة لمطوري Java الذين يعملون مع أنظمة مؤسسية كبيرة أو خدمات مصغرة، أصبح المستودع الأحادي حلاً شائعًا بشكل متزايد.
مزايا المستودع الأحادي في Java واضحة:
- إصدار موحد للتبعيات: تستخدم جميع الوحدات إصدارًا واحدًا من المكتبات، مما يلغي التعارضات (classpath hell).
- إعادة هيكلة مبسطة: تغيير API في وحدة واحدة يظهر فورًا في جميع الوحدات التابعة.
- تاريخ تغييرات شامل: يمكن أن يحتوي الالتزام الواحد (commit) على تغييرات في عدة وحدات، مما يبسط عملية التصحيح.
- التوحيد القياسي: قواعد موحدة لأسلوب الكود، والفحص الآلي (linting)، وCI/CD للمشروع بأكمله.
ومع ذلك، يتطلب المستودع الأحادي تنظيمًا جيدًا. في هذه المقالة، سنشرح كيفية هيكلة مشروع Java بشكل صحيح في مستودع أحادي باستخدام Maven وGradle.
الجزء الرئيسي: تنظيم المستودع الأحادي في Java
1. هيكل الدلائل: النهج المعياري (modular)
أساس المستودع الأحادي هو الهيكل المعياري. تمثل كل وحدة كيانًا مستقلاً (مكتبة، خدمة، أداة). دعنا نلقي نظرة على هيكل نموذجي لمشروع Java:
my-monorepo/├── build.gradle # ملف البناء الجذر (Gradle)├── settings.gradle # قائمة الوحدات├── gradle.properties # الإعدادات العامة├── gradle/│ └── wrapper/├── common/ # المكتبات العامة│ ├── common-utils/ # الأدوات (سلاسل، تواريخ)│ └── common-dto/ # DTO لتبادل البيانات├── services/ # الخدمات المصغرة│ ├── user-service/ # خدمة المستخدمين│ └── order-service/ # خدمة الطلبات├── libs/ # المكتبات الداخلية│ └── logging-lib/ # مكتبة التسجيل (logging)├── tests/ # اختبارات التكامل/الاختبارات الشاملة│ └── e2e-tests/└── buildSrc/ # الإضافات والإعدادات العامةتحتوي كل وحدة داخلية على هيكل Maven/Gradle قياسي:
user-service/├── build.gradle├── src/│ ├── main/│ │ ├── java/│ │ │ └── com/example/user/│ │ │ ├── controller/│ │ │ ├── service/│ │ │ └── repository/│ │ └── resources/│ │ └── application.yml│ └── test/│ └── java/└── Dockerfile2. إدارة التبعيات: Maven BOM وGradle Version Catalog
المشكلة الرئيسية في المستودع الأحادي هي مزامنة إصدارات التبعيات. في Java، يتم حل هذه المشكلة بطريقتين.
الخيار 1: Maven BOM (Bill of Materials)
يتم إنشاء POM جذر يعلن عن جميع إصدارات التبعيات. تستخدم الوحدات الفرعية dependencyManagement:
<!-- pom.xml (الجذر) --><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.2.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>common-utils</artifactId> <version>1.0.0</version> </dependency> </dependencies></dependencyManagement>الخيار 2: Gradle Version Catalog
في ملف gradle/libs.versi