التحليل إلى وحدات ومكونات
التحليل إلى وحدات ومكونات
بمجرد وضع الهيكل المعماري، يواجه المحلل وفريق التصميم سؤالاً جوهرياً: أين بالضبط ترسم الحدود؟ يُعدّ التحليل إلى أجزاء — أي فن تقسيم النظام إلى وحدات أصغر وأكثر قابلية للإدارة — المحدد الرئيسي لسهولة البناء والاختبار والصيانة على مر السنين. تحكم هذا القرار قوتان: التماسك (مدى انتماء العناصر داخل الوحدة الواحدة لبعضها) والاقتران (مدى الارتباط الوثيق بين وحدتين مختلفتين).
التماسك: مدى تلاحم الوحدة الداخلي
يقيس التماسك درجة ترابط المسؤوليات داخل الوحدة الواحدة. كلما ارتفع التماسك، سهل فهم الوحدة واختبارها وإعادة استخدامها. ثمة تسلسل هرمي كلاسيكي لمستويات التماسك، من الأضعف إلى الأقوى:
- العشوائي — تُجمَّع العناصر بشكل اعتباطي دون رابط منطقي (مثل فئة "أدوات مساعدة" تحتوي على توليد ملفات PDF وإرسال بريد إلكتروني وتحويل عملات). تجنبه كلياً.
- المنطقي — تؤدي العناصر عمليات متشابهة لكنها تُختار بناءً على راية تحكم (مثل دالة واحدة تتعامل مع
createوupdateوdeleteعبر معامل). أفضل من العشوائي لكنه لا يزال هشاً. - الزمني — تُنفَّذ العناصر في الوقت ذاته (كجمع كل مهام بدء التشغيل في وحدة واحدة). مقبول فقط لإجراءات التهيئة.
- الإجرائي — تتبع العناصر تسلسلاً من الخطوات (مثل
validateInput → formatData → saveRecordفي وحدة واحدة). شائع لكنه يخلط المسؤوليات. - التواصلي — تعمل العناصر على مجموعة البيانات ذاتها (كل ما يتعلق بكيان
Order). جيد: الوحدات المحورية للبيانات متماسكة بطبيعتها. - التسلسلي — يُغذّي خرج عنصر ما مدخل العنصر التالي مباشرةً (أسلوب خط الأنابيب). تماسك ممتاز.
- الوظيفي — يُسهم كل عنصر في غرض واحد محدد بوضوح (مثل وحدة مهمتها الوحيدة حساب تكلفة الشحن). هذا هو الهدف المنشود.
الاقتران: مدى الترابط بين وحدتين
يقيس الاقتران درجة الاعتمادية المتبادلة بين الوحدات. الاقتران الشديد يعني أن أي تغيير في وحدة ما سيفرض تغييرات في وحدة أخرى — ظاهرة "تأثير التموج" التي تجعل الأنظمة هشة. وللاقتران أيضاً طيف من الأسوأ إلى الأفضل:
- اقتران المحتوى — تقرأ وحدة ما الحالة الداخلية لوحدة أخرى أو تعدّلها مباشرةً. كارثي ولا يُقبل قط.
- الاقتران العام — تتشارك وحدات متعددة متغيراً عاماً. هش؛ تجنبه في الكود الإنتاجي.
- اقتران التحكم — تمرر وحدة ما راية تتحكم في منطق وحدة أخرى. إشارة إلى ضرورة التقسيم.
- الاقتران بالطوابع — تتشارك الوحدات بنية بيانات مركّبة لكنها تستخدم جزءاً منها فقط (إرسال كائن
Customerكامل في حين أن البريد الإلكتروني فقط هو المطلوب). - الاقتران بالبيانات — تتواصل الوحدات فقط عبر معاملات بسيطة محددة بوضوح. هذا هو الهدف: كل وحدة لا تعرف شيئاً عن الآلية الداخلية للأخرى.
رسم حدود المكونات عملياً
لنأخذ نظام حجز مواعيد عيادة طبية. حدد المحلل أربعة مجالات وظيفية رئيسية من المتطلبات: الخدمة الذاتية للمريض، والجدولة الطبية، والفوترة، والإشعارات. تجميع كل ما يمسّ سجل المريض في وحدة PatientModule ضخمة هو تحليل رديء. أما التحليل الأمثل فيتبع التماسك الوظيفي:
PatientRegistration— إنشاء ملفات المرضى وإدارتها.AppointmentScheduler— التحقق من التوافر، الحجز، إعادة الجدولة، الإلغاء.BillingEngine— حساب الرسوم، إصدار الفواتير، معالجة المدفوعات.NotificationService— إرسال تأكيدات وتذكيرات عبر الرسائل القصيرة والبريد الإلكتروني.
تكشف كل مكوّن عن واجهة ضيقة وصريحة للمكونات الأخرى. لا يرسل AppointmentScheduler الرسائل مباشرةً — بل يستدعي NotificationService.sendConfirmation(appointmentId) ويترك لذلك المكوّن تحديد القناة والقالب والتوصيل. هذا هو الاقتران بالبيانات في أحسن تجلياته.
الاقتران والتماسك في مراجعة تصميم حقيقية
تخيّل متجراً إلكترونياً. تضمّنت المسودة الأولى لمطور البرمجيات وحدة OrderManager واحدة تتولى التحقق من صحة السلة، وحجز المخزون، وشحن البطاقة، وإرسال رسالة تأكيد، وتسجيل أحداث التحليل. كل المسؤوليات مجمّعة معاً. تظهر مشكلة الاقتران فوراً: إذا غيّر مزود الدفع واجهته البرمجية، وجب على المطور فتح OrderManager مخاطراً بإحداث خطأ في منطق البريد الإلكتروني غير ذي الصلة. يرصد المحلل هذا باستخدام اختبار الجملة الواحدة ويوصي بتقسيم الوحدة. يتحوّل التصميم النهائي إلى أربعة مكونات: CartValidator، وInventoryReserver، وPaymentProcessor، وOrderNotifier، تتواصل جميعها فقط عبر معرّف الطلب orderId.
تحديد الواجهات بين المكونات
رسم الحدود وحده لا معنى له دون تحديد ما يعبرها. يجب أن يقترن كل حد بين مكوّنين بـعقد واجهة صريح يصف ما يقبله المكوّن وما يُعيده. في هذه المرحلة من التحليل لا يحتاج العقد أن يكون كوداً — يكفي وصف منظّم:
هذه المواصفة محايدة تقنياً — تنطبق سواء كان التطبيق خدمة Java أو دالة Python أو نقطة REST. يكتبها المحلل ويلتزم بها المطور. هذا الفصل بين ماذا وكيف هو جوهر التفكير القائم على المكونات.
من مخطط الفئات إلى حدود المكونات
أنت تعرف بالفعل كيف ترسم مخطط الفئات. يستخدم تحليل المكونات ذلك المخطط مدخلاً. اجمع الفئات التي تتعاون بكثافة (عدد تفاعل عالٍ على مخطط الفئات) في المكوّن ذاته. ينبغي أن تتفاعل الفئات التي تتقاطع عبر حدود المكونات المستقبلية فقط عبر ارتباطات محددة بوضوح، ويُفضّل أن تكون بمضاعفة محدودة وبإتجاهية واضحة. في نموذج مجال شركة لوجستية مثلاً، قد يظهر أن Route وStop وVehicle مترابطة بشكل وثيق — تنتمي إلى مكوّن RouteManagement. أما Invoice وPaymentRecord فينتميان إلى مكوّن Billing منفصل. يحتاج مخطط الطرق فقط أن يعرف التكلفة النهائية، لا الطريقة التي يحسبها بها مكوّن الفوترة.
التماسك والاقتران ليسا مُثُلاً مجردة — بل قرارات تصميمية لها تكاليف مباشرة. تكلف الأنظمة ذات التماسك المنخفض والاقتران العالي عادةً ضعفاً إلى خمسة أضعاف تكلفة الصيانة مقارنةً بالبدائل المحللة جيداً. دورك كمحلل هو إظهار تلك القرارات بصورة صريحة وقابلة للتتبع قبل كتابة سطر كود واحد.