مخططات آلة الحالة
مخططات آلة الحالة
لكل كائن في النظام تاريخ حياة خاص به. يُقدَّم الطلب عبر الإنترنت ثم يُؤكَّد ثم يُشحن ثم يُسلَّم — أو قد يُلغى في أي لحظة خلال هذا المسار. الكتاب في المكتبة متاح، ثم مُعار، ثم مُعاد، ثم ربما محجوز. مخطط آلة الحالة (يُعرف أيضًا بـمخطط الحالات) هو أداة UML التي تُسجِّل هذا التاريخ بدقة: يعرض كل حالة يمكن أن يكون عليها الكائن وكل حدث يتسبب في انتقاله من حالة إلى أخرى.
تكتسب مخططات آلة الحالة قيمتها الكبرى حين يعتمد سلوك الكائن اعتمادًا كبيرًا على حالته الراهنة — فالحدث ذاته قد يُفضي إلى إجراءات مختلفة بحسب موقع الكائن في دورة حياته. وبالنسبة لمحلل الأنظمة، يُجبرك رسم آلة الحالة على السؤال: "ما كل ما يمكن أن يحدث لهذا الكيان، وفي أي ظروف يكون ذلك صحيحًا؟"
عناصر الترميز الأساسية
تعتمد مخططات آلة الحالة على مفردات صغيرة ودقيقة:
- الحالة الابتدائية الوهمية — دائرة مملوءة (
●). كل آلة حالة تبدأ منها. ليست حالة حقيقية؛ هي ببساطة سهم الدخول. - الحالة — مستطيل ذو زوايا مستديرة يحمل اسم الحالة (مثل:
Pending،Shipped). الحالة تمثل وضعًا ينتظر فيه الكائن حدوث شيء ما. - الانتقال — سهم موجَّه من حالة إلى أخرى، مُعنوَن بـالحدث المُشغِّل، والحارس الاختياري بين قوسين معكوفين، والإجراء الاختياري بعد شرطة مائلة:
event [guard] / action. - الحالة النهائية — رمز العين الثور (دائرة مملوءة داخل حلقة). تنتهي عندها دورة حياة الكائن.
- الحدث (Event) هو شيء يحدث خارجيًا أو داخليًا يستطيع الكائن الاستجابة له (مثل: customerPays، timeout).
- الحارس (Guard) شرط منطقي بين قوسين معكوفين يجب أن يكون صحيحًا لكي ينطلق الانتقال (مثل: [stock > 0]).
- الإجراء (Action) هو النشاط الذي يُنفَّذ لحظة انطلاق الانتقال (مثل: / sendConfirmationEmail).
نمذجة دورة حياة الطلب
تأمَّل كائن Order في متجر إلكتروني. ينتقل الطلب عبر مراحل محددة بدقة من اللحظة التي يُقدِّمه فيها العميل حتى لحظة تسليمه أو إلغائه. إليك آلة الحالة التي تُجسِّد دورة الحياة الكاملة:
قراءة المخطط
سِر عبر المخطط من اليسار إلى اليمين ومن الأعلى إلى الأسفل:
- يبدأ الطلب في حالة Pending فور إرساله.
- عند وقوع حدث customerPays، ينتقل الطلب إلى Payment Received.
- حين يحاول النظام تأكيد الطلب، يُقيَّم الحارس
[stock > 0]. إن كانت المخزون متاحًا، دخل الطلب في Processing. أما إن كان المخزون صفرًا، انطلق إجراءrefundPaymentوعاد الطلب إلى Pending حتى يختار العميل بديلًا. - عند إرسال المستودع للبضاعة (حدث dispatch)، يُطلق النظام إجراء
notifyCustomerوينتقل الطلب إلى Shipped. - بمجرد تأكيد التوصيل (حدث delivered)، يصل الطلب إلى Delivered ثم يُغلق.
- في أي وقت قبل الإرسال (Pending أو Payment Received أو Processing)، يُحرِّك حدث cancel الطلبَ إلى Cancelled الذي يُغلق هو الآخر.
شروط الحارس تُرسِّخ قواعد العمل
الحراس هي المكان الذي تعيش فيه قواعد العمل داخل آلات الحالة. في مخطط الطلب، يُشفِّر [stock > 0] سياسة المخزون. تأمَّل نظام حجز موعد في عيادة:
- ينتقل الموعد من
RequestedإلىConfirmedفقط إن كان[الطبيب متاح في التاريخ المطلوب]. - ينتقل إلى
Completedفقط إن كان[المريض سجَّل حضوره]. - حدث
no-showمع الحارس[لم يصل المريض]يُحوِّله إلى حالةNo-Showقد تُشغِّل تذكيرًا بإعادة الحجز.
بدون الحراس، ستكون الانتقالات غامضة. الحراس تحوِّل المخطط من مسودة إلى مواصفة يمكن للمطورين تنفيذها مباشرة.
الانتقالات الداخلية وإجراءات الدخول والخروج
يمكن أن تحتوي الحالة على أقسام اختيارية إضافية:
entry / action— يُنفَّذ مرة واحدة عند دخول الحالة (مثل: entry / startPaymentTimer).exit / action— يُنفَّذ مرة واحدة عند مغادرة الحالة (مثل: exit / logTimestamp).do / activity— نشاط مستمر طوال فترة البقاء في الحالة (مثل: do / processCreditCard).
مثال ثانٍ: كتاب المكتبة
إرشادات رسم مخططات آلة الحالة
- ابدأ بالمسار السعيد. ارسم التدفق الطبيعي أولًا — تسلسل الحالات التي يمر بها الكائن حين يسير كل شيء على ما يرام.
- أضف مسارات الاستثناء والإلغاء. اسأل: "ماذا يمكن أن يسوء في كل حالة؟ ما الأحداث الخارجية التي يمكن أن تفرض خروجًا مبكرًا؟"
- سمِّ الحالات كأسماء أو صفات (Pending، Confirmed، Overdue)، لا أفعالًا.
- سمِّ الأحداث كعبارات فعلية أو أسماء إشارات (customerPays، dueDatePassed، cancel).
- تحقق من الاكتمال — يجب أن تمتلك كل حالة انتقالًا للخروج على الأقل (عدا الحالة النهائية). إذا كان الكائن قادرًا على البقاء في حالة ما إلى الأبد، فنمذج ذلك صراحةً أو أعد النظر في التصميم.
- تجنب كثرة الحالات. إذا تجاوزت ثماني إلى عشر حالات في مخطط واحد، فكِّر في تجميع بعضها باستخدام الحالات المركبة (موضوع الدرس القادم).
تُعدُّ مخططات آلة الحالة من أكثر الطرق مباشرةً للانتقال من محادثة المتطلبات إلى تصميم قابل للتنفيذ. حين يرى المطور آلة حالة مرسومة بإتقان، يمكنه تحويلها مباشرة إلى قائمة تعداد (enum) وعمود حالة ومجموعة من قواعد التحقق في قاعدة الكود — وهذا بالضبط هو مستوى الدقة الذي يجب أن يسعى محلل الأنظمة لتقديمه.