UML: مخططات الفئات والكائنات

مشروع: مخطط أصناف النطاق

18 دقيقة الدرس 10 من 10

مشروع: مخطط أصناف النطاق

على مدار الدروس التسعة السابقة، أتقنت كل لبنة من لبنات مخططات الأصناف UML: الأصناف وأقسامها الثلاثة، واستخراج الأصناف من المتطلبات، والارتباطات مع التعدد، والتجميع والتركيب، والتعميم، وأصناف الارتباط والاعتماديات، والواجهات والأصناف المجردة، ومخططات الكائنات. هذا الدرس الختامي يجمع كل ذلك في مشروع واحد حقيقي — بناء مخطط أصناف نطاق كامل انطلاقاً من سيناريو عمل واقعي.

يُعدّ مخطط أصناف النطاق المخرج الرئيسي للمحلل في نهاية مرحلة التحليل. يرصد مفردات النطاق — كل مفهوم جوهري وخصائصه والعلاقات بين المفاهيم — دون الالتزام بأي تقنية أو تصميم قاعدة بيانات محدد. فكر فيه كوثيقة متطلبات دقيقة ومرئية يقرؤها أصحاب المصلحة والمطورون على حد سواء.

ما الذي يجعل المخطط "مكتملاً"؟ يشتمل مخطط أصناف النطاق الكامل على: جميع الأصناف الرئيسية مع قسمَي الاسم والخصائص، وجميع العلاقات (ارتباط، تجميع، تركيب، تعميم) مع تسميات التعدد الصحيحة، وأسماء الأدوار حيثما أفادت، وأصناف الارتباط عندما تحمل العلاقة خصائص خاصة بها، والأصناف المجردة والواجهات حيثما يستدعيها النطاق.

السيناريو: نظام حجز مواعيد في عيادة طبية

أجريت مقابلات مع مدير العيادة وجمعت المتطلبات التالية. اقرأها بعناية — مهمتك تحويلها إلى مخطط أصناف نطاق.

  1. تضم العيادة أطباء متعددين. لكل طبيب اسم وتخصص (كأمراض القلب) ورقم ترخيص وجدول عمل.
  2. يُسجّل المرضى في العيادة. لكل مريض اسم وتاريخ ميلاد ورقم هاتف ورقم وثيقة تأمين.
  3. يستطيع المريض حجز مواعيد واحد أو أكثر. يُسجّل الموعد تاريخاً ووقت بداية وحالة (مجدول/مكتمل/ملغى) وسبب الزيارة.
  4. كل موعد مع طبيب واحد بالضبط.
  5. عند اكتمال الموعد، قد يُنشئ الطبيب سجلاً طبياً. يحتوي السجل على التشخيص والأدوية الموصوفة وتعليمات المتابعة. كل سجل طبي يعود إلى مريض واحد بالضبط.
  6. تُنظَّم الأطباء في أقسام (كالقلبية والعظمية). للقسم اسم وطبيب رئيس. كل طبيب ينتمي إلى قسم واحد بالضبط.
  7. كل من المريض والطبيب شخص. لكل شخص اسم وعنوان بريد إلكتروني في النظام.
  8. تقدّم العيادة خدمات متنوعة (كتحليل الدم والأشعة والاستشارة). قد يشمل الموعد خدمة واحدة أو أكثر، ولكل خدمة رسوم للفوترة. يُسجَّل للمزيج من الموعد والخدمة ما إذا كانت الخدمة قد نُفِّذت فعلاً.
  9. يستخدم النظام آلية إشعارات. الإشعار إما رسالة SMS أو بريد إلكتروني. يُرسَل كل إشعار إلى شخص واحد ويرتبط بموعد واحد.

الخطوة الأولى — تحديد الأصناف

استقراء المتطلبات بحثاً عن الأسماء يُنتج قائمة مرشحي الأصناف:

  • Person (مجرد — متطلب 7)
  • Patient (يخصص Person)
  • Doctor (يخصص Person)
  • Appointment
  • MedicalRecord
  • Department
  • Service
  • Notification (مجرد — متطلب 9 يُلمح إلى نوعين)
  • SmsNotification وEmailNotification

أسماء هي خصائص لا أصناف: التخصص، رقم الترخيص، التشخيص، الرسوم — تصبح حقول خصائص لا مربعات أصناف.

الخطوة الثانية — تحديد الخصائص والعمليات

  • Person: - name: String، - email: String
  • Patient: - dateOfBirth: Date، - phone: String، - insurancePolicyNo: String
  • Doctor: - specialization: String، - licenseNo: String
  • Department: - name: String
  • Appointment: - date: Date، - startTime: Time، - status: String، - reasonForVisit: String
  • MedicalRecord: - diagnosis: String، - medications: String، - followUpInstructions: String
  • Service: - serviceName: String، - standardFee: Decimal
  • Notification: - sentAt: DateTime، - message: String
  • SmsNotification: - phoneNumber: String
  • EmailNotification: - toAddress: String

الخطوة الثالثة — رسم العلاقات

بالمرور على كل متطلب:

  • Person → Patient / Doctor: تعميم (سهام مثلث مجوف تشير نحو Person). Person مجرد.
  • Department ◆→ Doctor: تركيب — الطبيب موجود ضمن قسم؛ 1 قسم لـ1..* أطباء.
  • Department → Doctor (headDoctor): ارتباط موجّه بدور headDoctor، تعدد 1.
  • Patient → Appointment: ارتباط؛ مريض واحد لـ0..* مواعيد.
  • Doctor → Appointment: ارتباط؛ كل موعد مع 1 طبيب، والطبيب لديه 0..* مواعيد.
  • Appointment → MedicalRecord: ارتباط؛ 0..1 سجل لكل موعد (المكتملة فقط).
  • MedicalRecord → Patient: ارتباط؛ كل سجل لـ1 مريض، والمريض له 0..* سجلات.
  • Appointment ↔ Service: صنف ارتباط AppointmentService يحمل performed: Boolean وchargedFee: Decimal.
  • Notification → Person / Appointment: ارتباطان موجّهان.
  • Notification → SmsNotification / EmailNotification: تعميم. Notification مجرد.

مخطط أصناف النطاق الكامل

يُظهر المخطط أدناه النموذج الكامل. اقرأه من أعلى لأسفل: هرم Person المجرد على اليسار، وتركيب Department-Doctor في الوسط العلوي، وسلسلة الحجز (Patient → Appointment → MedicalRecord) عبر المنتصف، وصنف الارتباط للخدمات في الأسفل، وهرم الإشعارات على اليمين.

Complete domain class diagram for a clinic appointment booking system Person - name: String - email: String (abstract) Patient - dateOfBirth: Date - phone: String - insurancePolicyNo: String Doctor - specialization: String - licenseNo: String Department - name: String + listDoctors() 1 1..* headDoctor Appointment - date: Date - startTime: Time - status: String - reasonForVisit: String + cancel() 1 0..* 1 0..* MedicalRecord - diagnosis: String - medications: String - followUpInstructions: String 1 0..1 0..* records 1 Service - serviceName: String - standardFee: Decimal 1 * * AppointmentService - performed: Boolean - chargedFee: Decimal Notification - sentAt: DateTime - message: String (abstract) SmsNotification - phoneNumber: String EmailNotif. - toAddress: String sent to 1 Person re: 1 Appointment Legend Generalization Composition Association Assoc. class link
مخطط أصناف النطاق الكامل لنظام حجز مواعيد العيادة. يضم المخطط التسعة أصناف مع الخصائص والعلاقات وتسميات التعدد وصنف الارتباط والأصناف المجردة وهرميات التعميم.

الخطوة الرابعة — مراجعة النموذج والتحقق منه

قبل تسليم المخطط لأصحاب المصلحة أو المطورين، مرّ على قائمة التحقق هذه:

  1. كل متطلب قابل للتتبع. كل من المتطلبات التسع يقابله عنصر في المخطط على الأقل. إن لم يُمثَّل متطلب ما، فالنموذج ناقص.
  2. التعدد صحيح على الطرفين. اقرأ كل ارتباط في الاتجاهين: "مريض واحد لديه صفر أو أكثر من المواعيد"، و"كل موعد يعود إلى مريض واحد بالضبط". يجب أن يكون كلا الاتجاهين منطقياً من الناحية التجارية.
  3. لا توجد خاصية متنكرة في هيئة صنف. "التشخيص" حقل في MedicalRecord لا صنف مستقل، لأنه لا علاقات له ولا عمليات خاصة.
  4. التعميم يجتاز اختبار "هو نوع من". Patient هو Person. Doctor هو Person. SmsNotification هو Notification. جميعها صحيحة.
  5. صنف الارتباط مبرر. يحمل AppointmentService خصائص خاصة به (performed, chargedFee) لا تنتمي لا إلى Appointment ولا إلى Service منفردَين. هذا يبرر صنف الارتباط.
  6. الأصناف المجردة لا تُستنسخ مباشرة. لا تُنشئ أي قاعدة عمل كائن Person عارياً أو Notification عارية — توجد فقط كائنات الأصناف الفرعية.
أسلوب جلسة المراجعة مع أصحاب المصلحة: قدّم المخطط بتتبع سيناريو واحد متكامل. مثلاً: "ماريا مريضة تحجز موعداً مع الدكتور أحمد الذي ينتمي إلى قسم أمراض القلب. في الموعد يُنفَّذ خدمة تحليل الدم، فيُنشأ سجل AppointmentService بـperformed=true ويُسجَّل الرسم. بعد الزيارة يُنشأ MedicalRecord في ملف ماريا وتصلها SmsNotification تؤكد موعد المتابعة." تتبع قصة حقيقية عبر المخطط هو أسرع وسيلة لأصحاب المصلحة للتحقق من صحته.

أخطاء شائعة في مخططات أصناف النطاق

  • غياب التعدد. الخط غير المُعنوَن يثير الالتباس. عنوِن الطرفين دائماً.
  • حشر كل شيء في صنف ضخم واحد. إن تجاوز صنف ما ثماني خصائص أو عشراً، ابحث عن مفاهيم خفية تستحق أصنافاً مستقلة.
  • الإفراط في استخدام التركيب. استخدم الماسة المملوءة فقط حين يعتمد وجود الكائن الابن فعلياً على الأب — لا مجرد الانتماء الضمني.
  • نسيان صنف الارتباط. عندما تحمل علاقة متعدد-لمتعدد بياناتها الخاصة، يجب أن تسكن في صنف ارتباط، لا أن تُدسّ في أحد الطرفين.
  • الخلط بين التحليل والتصميم. مخطط أصناف النطاق لا يُظهر مفاتيح أساسية ولا مفاتيح خارجية ولا جداول ولا أنواعاً مرتبطة بإطار عمل بعينه. ابقِ النموذج محايداً تقنياً خلال مرحلة التحليل.
زحف النطاق في المخطط: قد يغري المحلل إضافة أصناف جديدة كلما استحضر حالات طرفية. انضبط وموِّل فقط ما تنصّ عليه المتطلبات الحالية صراحةً. المتطلبات الجديدة تُنتج مراجعات جديدة للمخطط — لا مسودة أولى منتفخة.

ما التالي؟

لقد أكملت الآن درس مخططات الأصناف والكائنات UML. مخطط أصناف النطاق هو الأساس لنشاطين تاليين يُتناولان في الدروس القادمة:

  • تصميم قاعدة البيانات — تحويل الأصناف إلى جداول، ومعالجة التعميمات باستراتيجيات الجدولة، وتحويل أصناف الارتباط إلى جداول وصل.
  • النمذجة السلوكية — مخططات التسلسل وآلات الحالة التي تُظهر كيف تتفاعل هذه الأصناف في وقت التشغيل.

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

اكتمل الدرس!

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