Laravel المتقدم

Laravel للمؤسسات: مراجعة المعمارية

20 دقيقة الدرس 40 من 40

Laravel للمؤسسات: مراجعة المعمارية

يتطلب بناء وصيانة تطبيقات Laravel على مستوى المؤسسات اهتمامًا دقيقًا بالمعمارية وجودة الكود والتعاون الجماعي والاستدامة طويلة الأجل. في هذا الدرس الأخير، سنراجع أفضل الممارسات لمراجعة الكود وقرارات المعمارية وإدارة الديون التقنية واستراتيجيات التوسع وأنماط الفريق.

أفضل ممارسات مراجعة الكود

تعد مراجعات الكود الفعالة ضرورية للحفاظ على جودة الكود ومشاركة المعرفة:

# قالب طلب السحب (.github/pull_request_template.md) ## الوصف وصف موجز للتغييرات ## نوع التغيير - [ ] إصلاح خطأ (تغيير لا يكسر الوظائف الموجودة) - [ ] ميزة جديدة (تغيير لا يكسر الوظائف الموجودة) - [ ] تغيير مدمر (إصلاح أو ميزة تسبب تغيير الوظائف الموجودة) - [ ] تحديث التوثيق ## التغييرات المنفذة - قائمة التغييرات الرئيسية - تضمين السياق ذي الصلة - ربط المشكلات ذات الصلة ## الاختبار - [ ] اختبارات الوحدة مضافة/محدثة - [ ] اختبارات الميزات مضافة/محدثة - [ ] الاختبار اليدوي مكتمل - [ ] جميع الاختبارات تمر ## تغييرات قاعدة البيانات - [ ] الترحيلات مضافة - [ ] البذور محدثة - [ ] توثيق قاعدة البيانات محدث ## تأثير الأداء - [ ] لا يوجد تأثير على الأداء - [ ] الأداء محسّن - [ ] الأداء انخفض (اشرح سبب القبول) ## اعتبارات الأمان - [ ] لا توجد آثار أمنية - [ ] الأمان تمت مراجعته والموافقة عليه - [ ] تم معالجة المخاوف الأمنية ## قائمة التحقق - [ ] الكود يتبع إرشادات نمط المشروع - [ ] قمت بمراجعة الكود الخاص بي - [ ] علقت على الكود في المناطق الصعبة الفهم - [ ] قمت بتحديث التوثيق - [ ] لم يتم إنشاء تحذيرات جديدة - [ ] أضفت اختبارات تثبت عمل الإصلاح/الميزة - [ ] التغييرات التابعة مدمجة ## لقطات الشاشة (إن وجدت) ## ملاحظات إضافية
ملاحظة: قم بأتمتة ما تستطيع بأدوات مثل PHP CS Fixer و PHPStan و Larastan و GitHub Actions. ركز المراجعة البشرية على منطق الأعمال وقرارات المعمارية والآثار الأمنية.

قائمة التحقق من مراجعة الكود

المجالات الرئيسية التي يجب التركيز عليها أثناء مراجعات الكود:

<?php /** * قائمة التحقق من مراجعة الكود * * الوظيفة * - هل يقوم الكود بما يفترض أن يفعله؟ * - هل يتم التعامل مع الحالات الحدية؟ * - هل معالجة الأخطاء مناسبة؟ * - هل تم التحقق من المدخلات؟ * * المعمارية * - هل يتبع مبادئ SOLID؟ * - هل الكود منفصل بشكل صحيح (المخاوف، الطبقات)؟ * - هل يتم حقن التبعيات بدلاً من إنشائها؟ * - هل يتم استخدام نمط التصميم الصحيح؟ * * الأمان * - هل تم تطهير جميع المدخلات؟ * - هل تم فحص التفويض؟ * - هل تم منع حقن SQL؟ * - هل البيانات الحساسة مشفرة؟ * - هل الحماية من CSRF موجودة؟ * * الأداء * - هل تم تجنب استعلامات N+1؟ * - هل تم تنفيذ التخزين المؤقت حيث يكون مناسبًا؟ * - هل فهارس قاعدة البيانات موجودة؟ * - هل يتم استخدام الترقيم للبيانات الكبيرة؟ * - هل الوظائف في قائمة الانتظار للمهام الطويلة؟ * * الاختبار * - هل الاختبارات موجودة وشاملة؟ * - هل تغطي الاختبارات المسار السعيد والحالات الحدية؟ * - هل الاختبارات قابلة للقراءة والصيانة؟ * - هل تغطية الاختبار كافية (>80%)؟ * * قابلية الصيانة * - هل الكود موثق ذاتيًا؟ * - هل المناطق المعقدة معلقة؟ * - هل تم اتباع اتفاقيات التسمية؟ * - هل الكود DRY (لا تكرر نفسك)؟ * - هل يمكن فهم الكود بسهولة في 6 أشهر؟ */ // جيد: واضح، قابل للاختبار، قابل للصيانة class OrderProcessor { public function __construct( private PaymentGateway $paymentGateway, private InventoryService $inventory, private NotificationService $notifications ) {} public function process(Order $order): ProcessedOrder { DB::beginTransaction(); try { // التحقق من توفر المخزون $this->inventory->reserve($order->items); // معالجة الدفع $payment = $this->paymentGateway->charge( $order->customer, $order->total ); // تحديث حالة الطلب $order->markAsPaid($payment->id); $order->save(); DB::commit(); // إرسال الإشعارات بشكل غير متزامن ProcessOrderNotifications::dispatch($order); return new ProcessedOrder($order, $payment); } catch (InsufficientInventoryException $e) { DB::rollBack(); throw new OrderProcessingException('نفاد المخزون', 0, $e); } catch (PaymentFailedException $e) { DB::rollBack(); $this->inventory->release($order->items); throw new OrderProcessingException('فشل الدفع', 0, $e); } } } // سيء: صعب الاختبار، اقتران محكم، مسؤوليات غير واضحة class OrderController { public function process(Request $request) { $order = Order::find($request->order_id); // معالجة الدفع المضمنة $stripe = new \Stripe\StripeClient(config('stripe.secret')); $charge = $stripe->charges->create([ 'amount' => $order->total * 100, 'currency' => 'usd', 'customer' => $order->customer->stripe_id, ]); // لا توجد معاملة $order->status = 'paid'; $order->save(); // لا يوجد فحص للمخزون foreach ($order->items as $item) { $item->product->decrement('stock', $item->quantity); } // بريد إلكتروني متزامن (يحجب الطلب) Mail::to($order->customer)->send(new OrderConfirmation($order)); return redirect()->back(); } }

سجلات قرارات المعمارية (ADRs)

قم بتوثيق قرارات المعمارية الهامة للرجوع إليها في المستقبل:

# docs/adr/001-use-repository-pattern.md # 1. استخدام نمط المستودع للوصول إلى البيانات التاريخ: 2024-01-15 ## الحالة مقبول ## السياق نحتاج إلى طريقة متسقة للوصول إلى البيانات عبر التطبيق. نهجنا الحالي من استخدام نماذج Eloquent مباشرة في وحدات التحكم يؤدي إلى: - وحدات تحكم سمينة مع منطق الأعمال - صعوبة الاختبار (صعب محاكاة قاعدة البيانات) - أنماط استعلام غير متسقة عبر التطبيق - صعوبة تبديل مصادر البيانات في المستقبل ## القرار سنقوم بتنفيذ نمط المستودع لجميع الوصول إلى البيانات: - إنشاء واجهات المستودع في `app/Contracts/Repositories` - تنفيذ المستودعات في `app/Repositories` - ربط المستودعات بالواجهات في مزودي الخدمة - حقن المستودعات في وحدات التحكم/الخدمات عبر المنشئ مثال: ```php interface UserRepositoryInterface { public function findById(int $id): ?User; public function findByEmail(string $email): ?User; public function create(array $data): User; public function update(User $user, array $data): User; } class EloquentUserRepository implements UserRepositoryInterface { // التنفيذ باستخدام Eloquent } ``` ## العواقب ### إيجابي - تصبح وحدات التحكم نحيفة ومركزة - ينتقل منطق الأعمال إلى الخدمات - سهل الاختبار مع محاكاة المستودع - أنماط وصول متسقة للبيانات - يمكن تبديل التطبيقات (على سبيل المثال، لاستخدام MongoDB) ### سلبي - مزيد من الملفات والنموذج الأولي الأولي - منحنى تعليمي للمطورين المبتدئين - تكلفة أداء طفيفة (ضئيلة) ## البدائل المدروسة 1. **استمر في استخدام Eloquent مباشرة**: مرفوض بسبب الاقتران المحكم 2. **استخدم Query Builder في كل مكان**: مرفوض بسبب فقدان العلاقات 3. **إنشاء طبقة بيانات مخصصة**: مرفوض كهندسة زائدة ## المراجع - [Martin Fowler on Repository Pattern](https://martinfowler.com/eaaCatalog/repository.html) - مناقشة نمط المستودع Laravel في اجتماع الفريق (2024-01-10)
نصيحة: قم بإنشاء ADRs للقرارات مثل: الاختيار بين الحزم، وأنماط المعمارية، واختيارات تصميم قاعدة البيانات، واستراتيجيات التخزين المؤقت، ونهج النشر، واستراتيجيات إصدار API.

إدارة الديون التقنية

تحديد وترتيب أولويات ومعالجة الديون التقنية بشكل منهجي:

<?php /** * تتبع الديون التقنية * * استخدم علامات TODO بتنسيق موحد للتتبع: * * TODO: [الفئة] الوصف (تم الإنشاء: YYYY-MM-DD، الأولوية: عالية/متوسطة/منخفضة) * * الفئات: * - PERF: مشكلة الأداء * - SECURITY: مخاوف الأمان * - REFACTOR: الكود يحتاج إلى إعادة الهيكلة * - TEST: اختبارات مفقودة أو غير كافية * - DOCS: توثيق مفقود أو قديم * - TECH-DEBT: ديون تقنية عامة * - DEPRECATED: استخدام ميزة مهملة */ class UserService { // TODO: [PERF] تنفيذ التخزين المؤقت لتفضيلات المستخدم (تم الإنشاء: 2024-01-15، الأولوية: عالية) // حاليًا يصل إلى قاعدة البيانات في كل طلب. يجب التخزين المؤقت لمدة ساعة واحدة. // الجهد المقدر: ساعتان public function getUserPreferences(User $user): array { return $user->preferences()->get()->toArray(); } // TODO: [REFACTOR] استخراج التحقق من البريد الإلكتروني إلى خدمة منفصلة (تم الإنشاء: 2024-01-10، الأولوية: متوسطة) // هذه الطريقة تفعل الكثير. يجب نقل منطق البريد الإلكتروني إلى EmailVerificationService. // الجهد المقدر: 4 ساعات public function registerUser(array $data): User { $user = User::create($data); // منطق التحقق من البريد الإلكتروني $token = Str::random(60); $user->email_verification_token = $token; $user->save(); Mail::to($user)->send(new VerifyEmail($token)); return $user; } // TODO: [TEST] إضافة اختبارات تكامل لتعيين الدور (تم الإنشاء: 2024-01-08، الأولوية: عالية) // توجد فقط اختبارات الوحدة. نحتاج إلى اختبارات تغطي تفاعلات قاعدة البيانات الفعلية. // الجهد المقدر: 3 ساعات public function assignRole(User $user, string $role): void { $user->roles()->attach(Role::where('name', $role)->first()); } } // سجل الديون التقنية (docs/technical-debt.md) /* # سجل الديون التقنية ## أولوية عالية (معالجة خلال شهر واحد) 1. **تنفيذ التخزين المؤقت لتفضيلات المستخدم** (UserService.php:15) - التأثير: الأداء - تأخير 200 مللي ثانية في كل طلب - الجهد: ساعتان - المالك: فريق الخلفية 2. **إضافة اختبارات تكامل لتعيين الدور** (UserService.php:35) - التأثير: الجودة - لا توجد تغطية لميزة أمان حرجة - الجهد: 3 ساعات - المالك: فريق ضمان الجودة ## أولوية متوسطة (معالجة خلال 3 أشهر) 1. **استخراج التحقق من البريد الإلكتروني إلى خدمة منفصلة** (UserService.php:25) - التأثير: قابلية الصيانة - الخدمة تفعل الكثير - الجهد: 4 ساعات - المالك: فريق الخلفية ## مكتمل (احتفظ بها للرجوع إليها) - ~~الترحيل إلى Laravel 11~~ (مكتمل: 2024-01-20) - ~~تنفيذ تحديد المعدل على API~~ (مكتمل: 2024-01-18) */

استراتيجيات التوسع

نهج لتوسيع تطبيقات Laravel للتعامل مع النمو:

<?php /** * قائمة التحقق من التوسع الأفقي * * 1. تخزين الجلسة * - الانتقال من الملفات إلى قاعدة البيانات/Redis * - تكوين SESSION_DRIVER=redis في .env * * 2. تخزين ذاكرة التخزين المؤقت * - استخدم Redis/Memcached بدلاً من ذاكرة التخزين المؤقت للملفات * - تكوين CACHE_DRIVER=redis في .env * * 3. عمال قائمة الانتظار * - تشغيل عمال قائمة الانتظار على خوادم منفصلة * - استخدم Supervisor/systemd لإدارة العمال * - توسيع العمال بناءً على عمق قائمة الانتظار * * 4. تخزين الملفات * - استخدم S3/CloudFront للتحميلات * - تكوين FILESYSTEM_DISK=s3 في .env * * 5. قاعدة البيانات * - تنفيذ نسخ القراءة المتماثلة * - استخدام تجميع اتصالات قاعدة البيانات * - النظر في التجزئة للمقياس الضخم * * 6. موازنة الحمل * - إعداد موازن الحمل (AWS ALB، Nginx) * - تمكين الجلسات اللاصقة إذا لزم الأمر * - فحوصات الصحة لجميع خوادم التطبيق */ // config/database.php - تقسيم القراءة/الكتابة 'mysql' => [ 'read' => [ 'host' => [ env('DB_READ_HOST_1', '127.0.0.1'), env('DB_READ_HOST_2', '127.0.0.1'), ], ], 'write' => [ 'host' => [ env('DB_WRITE_HOST', '127.0.0.1'), ], ], 'sticky' => true, // تأكد من أن القراءات بعد الكتابة تذهب إلى خادم الكتابة // ... تكوين آخر ], // موسع Pod الأفقي (Kubernetes) /* apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: laravel-app spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: laravel-app minReplicas: 3 maxReplicas: 20 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 */ // مراقبة الأداء class PerformanceMiddleware { public function handle($request, Closure $next) { $start = microtime(true); $response = $next($request); $duration = (microtime(true) - $start) * 1000; // تسجيل الطلبات البطيئة if ($duration > 1000) { Log::warning('تم اكتشاف طلب بطيء', [ 'url' => $request->fullUrl(), 'method' => $request->method(), 'duration_ms' => $duration, 'memory_mb' => memory_get_peak_usage(true) / 1024 / 1024, 'queries' => DB::getQueryLog(), ]); } // إضافة رؤوس الأداء $response->headers->set('X-Response-Time', round($duration, 2) . 'ms'); $response->headers->set('X-Query-Count', count(DB::getQueryLog())); return $response; } }
تحذير: التحسين المبكر هو أصل كل الشرور. قم بتحليل تطبيقك أولاً لتحديد الاختناقات الفعلية قبل تنفيذ استراتيجيات توسع معقدة.

أنماط الفريق وسير العمل

إنشاء أنماط واضحة للتعاون الجماعي:

# إرشادات سير عمل الفريق ## سير عمل Git - **الفرع الرئيسي**: دائمًا جاهز للإنتاج، نشر من هنا - **فرع التطوير**: فرع التكامل للميزات - **فروع الميزات**: feature/ticket-number-description - **فروع إصلاح الأخطاء**: bugfix/ticket-number-description - **فروع الإصلاح السريع**: hotfix/issue-description (مباشرة من الرئيسي) ## اتفاقيات التسمية - **وحدات التحكم**: اسم مفرد + "Controller" (UserController) - **النماذج**: اسم مفرد (User، Post) - **جداول قاعدة البيانات**: جمع snake_case (users، blog_posts) - **الترحيلات**: action_table_name (create_users_table) - **الوظائف**: فعل + اسم (ProcessOrder، SendEmail) - **الأحداث**: فعل ماضي (OrderShipped، UserRegistered) - **المستمعون**: وصف الإجراء (SendShipmentNotification) - **الطلبات**: اسم + إجراء + "Request" (StoreUserRequest) - **الموارد**: اسم + "Resource" (UserResource) - **الاختبارات**: test_it_does_something (test_it_creates_user) ## تنظيم الكود حسب المجال app/ ├── Domain/ │ ├── Users/ │ │ ├── Models/User.php │ │ ├── Repositories/UserRepository.php │ │ ├── Services/UserService.php │ │ ├── Actions/CreateUser.php │ │ ├── Events/UserCreated.php │ │ └── Policies/UserPolicy.php │ ├── Orders/ │ │ ├── Models/Order.php │ │ ├── Repositories/OrderRepository.php │ │ ├── Services/OrderService.php │ │ ├── Actions/ProcessOrder.php │ │ └── Events/OrderProcessed.php │ └── ... └── Http/ ├── Controllers/ │ ├── Api/ │ └── Web/ ├── Middleware/ ├── Requests/ └── Resources/ ## معايير التوثيق - **README.md**: نظرة عامة على المشروع، تعليمات الإعداد، النشر - **docs/api/**: توثيق API (OpenAPI/Swagger) - **docs/adr/**: سجلات قرارات المعمارية - **docs/runbooks/**: إجراءات التشغيل - **CONTRIBUTING.md**: كيفية المساهمة - **CHANGELOG.md**: تاريخ الإصدار ## سير عمل طلب السحب 1. إنشاء فرع ميزة من التطوير 2. تنفيذ الميزة مع الاختبارات 3. مراجعة الكود الذاتية 4. إنشاء طلب سحب مع ملء القالب 5. معالجة ملاحظات CI/CD (الاختبارات، التحليل) 6. طلب المراجعة من عضوين في الفريق 7. معالجة تعليقات المراجعة 8. الدمج بعد 2 موافقات + اجتياز CI ## التواصل - **الوقوف اليومي**: 9:30 صباحًا - ما تم، ما سيتم، العوائق - **تخطيط السبرينت**: كل أسبوعين - خطة العمل القادم - **الاستعادة**: نهاية السبرينت - ما نجح، ما يجب تحسينه - **مراجعة الكود**: الرد خلال 4 ساعات خلال ساعات العمل - **قنوات Slack**: - #engineering: نقاش هندسي عام - #deployments: إشعارات النشر - #incidents: مشاكل الإنتاج - #code-review: أسئلة الكود السريعة
ملاحظة: الاتساق أهم من الكمال. قم بتوثيق اتفاقيات فريقك وفرضها من خلال الأتمتة (linters، CI/CD) بدلاً من الاعتماد على التطبيق اليدوي.

قائمة التحقق من جاهزية الإنتاج

قبل النشر إلى الإنتاج:

# قائمة التحقق من جاهزية الإنتاج ## الأمان - [ ] وضع التصحيح معطل (APP_DEBUG=false) - [ ] APP_KEY قوي تم إنشاؤه وتأمينه - [ ] فرض HTTPS - [ ] تكوين CORS بشكل صحيح - [ ] تنفيذ تحديد المعدل - [ ] التحقق من الإدخال على جميع النماذج - [ ] التحقق من منع حقن SQL - [ ] تمكين الحماية من XSS - [ ] تمكين الحماية من CSRF - [ ] اختبار المصادقة بدقة - [ ] مراجعة سياسات التفويض - [ ] تنفيذ مصادقة API (Sanctum/Passport) - [ ] تخزين الأسرار في متغيرات البيئة - [ ] تدوير بيانات اعتماد قاعدة البيانات - [ ] مراجعة تبعيات الطرف الثالث ## الأداء - [ ] تحسين الاستعلام مكتمل (لا يوجد N+1) - [ ] إضافة فهارس قاعدة البيانات - [ ] تنفيذ التخزين المؤقت - [ ] تجميع الأصول وتصغيرها - [ ] تكوين CDN للأصول الثابتة - [ ] تحسين الصورة - [ ] تنفيذ التحميل البطيء - [ ] الترقيم على مجموعات البيانات الكبيرة - [ ] عمال قائمة الانتظار للمهام الطويلة - [ ] اختبار الحمل مكتمل ## المراقبة - [ ] تتبع الأخطاء (Sentry، Bugsnag) - [ ] مراقبة أداء التطبيق (New Relic، Scout) - [ ] تجميع السجل (CloudWatch، Papertrail) - [ ] مراقبة وقت التشغيل (Pingdom، UptimeRobot) - [ ] مراقبة قاعدة البيانات - [ ] مراقبة قائمة الانتظار - [ ] مراقبة مساحة القرص - [ ] تكوين التنبيهات للمشاكل الحرجة ## النسخ الاحتياطي والاسترداد - [ ] النسخ الاحتياطية لقاعدة البيانات مؤتمتة - [ ] اختبار استعادة النسخ الاحتياطي - [ ] تكوين النسخ الاحتياطية لتخزين الملفات - [ ] توثيق خطة التعافي من الكوارث - [ ] تحديد RTO/RPO ## التوثيق - [ ] توثيق API مكتمل - [ ] توثيق عملية النشر - [ ] توثيق إجراء الاستعادة - [ ] توثيق متغيرات البيئة - [ ] تحديث مخططات المعمارية - [ ] إنشاء كتيبات للمشاكل الشائعة ## الاختبار - [ ] تغطية اختبار الوحدة >80% - [ ] اختبارات التكامل تمر - [ ] اختبارات النهاية إلى النهاية تمر - [ ] اختبار توافق المتصفح - [ ] التحقق من استجابة الموبايل - [ ] معايير إمكانية الوصول مستوفاة (WCAG) - [ ] اختبار اختراق الأمان مكتمل ## البنية التحتية - [ ] تكوين التوسع التلقائي - [ ] فحوصات صحة موازن الحمل - [ ] نسخ قراءة قاعدة البيانات المتماثلة (إذا لزم الأمر) - [ ] توفير خوادم Redis/cache - [ ] تكوين عمال قائمة الانتظار باستخدام Supervisor - [ ] تكوين شهادة SSL والتجديد التلقائي - [ ] تكوين DNS بشكل صحيح - [ ] مراجعة قواعد جدار الحماية
تمرين 1: قم بمراجعة مشروع Laravel موجود وإنشاء ADR لقرار معماري رئيسي واحد (على سبيل المثال، الاختيار بين نمط المستودع مقابل Active Record، monolith مقابل microservices، REST مقابل GraphQL). قم بتضمين السياق والقرار والعواقب والبدائل المدروسة.
تمرين 2: قم بإجراء تدقيق للديون التقنية لقاعدة الكود. حدد ما لا يقل عن 10 عناصر من الديون التقنية، وصنفها حسب الأولوية والتأثير، وقدر الجهد لكل منها، وأنشئ خارطة طريق لمعالجتها خلال الأشهر الثلاثة المقبلة. قم بتوثيق النتائج في سجل الديون التقنية.
تمرين 3: صمم استراتيجية توسع كاملة لتطبيق Laravel يتوقع أن ينمو من 1,000 إلى 100,000 مستخدم نشط يوميًا. قم بتضمين توسيع قاعدة البيانات (نسخ القراءة المتماثلة، تجميع الاتصالات)، واستراتيجية التخزين المؤقت، وعمال قائمة الانتظار، وتخزين الجلسة، وتخزين الملفات، والمراقبة. قم بإنشاء تقدير تكلفة وجدول زمني للتنفيذ.

الملخص

تهانينا على إكمال دورة Laravel المتقدمة! في هذا الدرس الأخير، تعلمت:

  • أفضل ممارسات مراجعة الكود وقوائم التحقق للحفاظ على الجودة
  • سجلات قرارات المعمارية لتوثيق القرارات المهمة
  • إدارة الديون التقنية بشكل منهجي
  • استراتيجيات التوسع للنمو الأفقي والعمودي
  • أنماط الفريق وسير العمل للتعاون الفعال
  • قائمة التحقق من جاهزية الإنتاج للثقة في النشر

لديك الآن المعرفة لبناء وصيانة وتوسيع تطبيقات Laravel على مستوى المؤسسات. استمر في التعلم، وابق على اطلاع بإصدارات Laravel، وشارك مع المجتمع، وأعط الأولوية دائمًا لجودة الكود والتعاون الجماعي.

اكتمل الدرس!

تهانينا! لقد أكملت جميع الدروس في هذا البرنامج التعليمي.