محتويات الدورة

Flutter / حدود التطبيق غير المتزامنة / الدرس 9

نماذج العرض وعقود المستودعات

شارك حالة التطبيق عبر اعتماديات صريحة وأتح أوامر ذات نتائج قابلة للملاحظة.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • افصل قرارات الواجهة عن الوصول للبيانات
  • احقن اعتمادا ضيق الواجهة
  • انشر انتقالات حالة متسقة

افصل قرارات الواجهة عن الوصول للبيانات

لا تحتاج الشاشة إلى معرفة هل جاءت سجلات الورش من الذاكرة أو ملف أو خدمة بعيدة. يملك المستودع عقد الوصول لبيانات التطبيق وقد ينسق التخزين المؤقت وسياسات المصادر. ويحوّل نموذج العرض معلومات المجال إلى حالة وأوامر تفيد الواجهة. هذه مسؤوليات وليست إلزاما بإنشاء صنف لكل جملة في المواصفات. ابدأ بحدود تسهّل اختبار قرار فعلي. يمكن لشاشة ثابتة صغيرة أن تبقى بسيطة، بينما تستفيد البيانات غير المتزامنة المشتركة عادة من مالك أوضح.

احقن اعتمادا ضيق الواجهة

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

dart مقتطف توضيحي من Dart أو Flutter؛ يتطلب بيئة SDK المبيّنة.
abstract interface class LabelRepository {
  Future<List<String>> loadLabels();
}
class FakeLabels implements LabelRepository {
  @override Future<List<String>> loadLabels() async => ['Maps', 'Rivers'];
}
الناتج المتوقع
The fake repository completes with Maps and Rivers without external I/O.

تسمح الواجهة بتنفيذات بديلة، بينما يوفر البديل المصطنع بيانات اختبار متوقعة.

انشر انتقالات حالة متسقة

يستخدم المقتطف الثاني ChangeNotifier كآلية مراقبة صغيرة. يتجاهل التحميل المكرر أثناء الانشغال، ويمحو الفشل السابق عند المحاولة التالية، ويرسل إشعارات حول العملية غير المتزامنة. تُعرض القائمة كلقطة غير قابلة للتعديل كي لا تغيّرها الواجهة بصمت. هذه سياسة ممكنة لتكرار الأمر؛ وقد تحتاج مهام أخرى إلى الاستبدال أو الطابور أو الرفض الصريح. لا تحل الآلية وحدها الطلبات المتقادمة أو التحرير أثناء العمل. يجب أن ينسق المالك العمر، ويضيف نموذج أغنى قواعد الجيل أو الإلغاء المناسبة.

dart مقتطف توضيحي من Dart أو Flutter؛ يتطلب بيئة SDK المبيّنة.
class LabelModel extends ChangeNotifier {
  LabelModel(this.repository);
  final LabelRepository repository;
  bool busy = false;
  String? failure;
  List<String> _labels = [];
  List<String> get labels => List.unmodifiable(_labels);
  Future<void> load() async {
    if (busy) return;
    busy = true; failure = null; notifyListeners();
    try { _labels = await repository.loadLabels(); }
    catch (_) { failure = 'Could not load labels'; }
    finally { busy = false; notifyListeners(); }
  }
}
الناتج المتوقع
A successful load ends with busy false, no failure, and the fake labels.

يتطلب استيراد foundation من Flutter وعقد المستودع السابق. يجب أن يبقى النموذج موجودا حتى انتهاء التحميل التوضيحي.

أتح الحالة دون تعديل اعتباطي

تقصّر الحقول العامة القابلة للتعديل المقتطف التعليمي، لكن واجهة الإنتاج ينبغي أن تحصر الكتابة في أوامرها وتتيح قراءات فقط أو كائنات حالة ثابتة. وإلا أمكن للواجهة تعيين busy دون بدء عمل أو استبدال قائمة دون إشعار. فضّل تمثيلا يصعّب الحالات المتناقضة. فحالة تحميل صريحة قد تحمل بيانات سابقة عند التحديث، بينما لا تحمل حالة فشل التحميل الأول بيانات. ولا تضاعف القيم المنطقية حتى تحتاج كل تركيبة إلى فقرة تشرح إمكانها.

حرّر بحسب الملكية ونطاق الاشتراك

عادة يحرّر نموذج العرض المنشأ للشاشة معها، لكن لا ينبغي لابن مؤقت تحرير نموذج نطاقه التطبيق. ويجب فصل المستمعين عند نهاية اشتراكاتهم. حدّد هل يسمح للأوامر بالاكتمال بعد انفصال آخر واجهة، وأبعد اعتماديات الواجهة عن المستودعات. تمرير BuildContext إلى مستودع ليعرض حوارا يربط سياسة التخزين بموقع عابر في الشجرة. أعد نتيجة مفهومة بدلا من ذلك ودع مالك الواجهة الحالي يقرر طريقة عرضها.

اختبر النتائج المرصودة وسياسة الأوامر

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

الأخطاء الشائعة وإصلاحها

تعدل الواجهة بيانات المستودع بصمت

لماذا يحدث؟
تسربت مجموعة قابلة للتعديل خارج حدود الملكية.
كيف تصلحه؟
أتح لقطات ثابتة وأوامر تعديل صريحة.
كيف تتجنب تكراره؟
اختبر عجز المستدعي عن تعديل الحالة عبر قارئاتها.

تؤدي ضغطتان إلى حفظ مكرر

لماذا يحدث؟
لا يملك الأمر سياسة للعمل المعلق.
كيف تصلحه؟
عطّل التكرار أو ارفضه عند المناسبة وحدّد تماثل العملية في الخادم بصورة مستقلة.
كيف تتجنب تكراره؟
اختبر التفعيل المتكرر قبل الاكتمال.

تحرّر شاشة مؤقتة حالة مشتركة

لماذا يحدث؟
لا تتفق ملكية الإنشاء والتحرير.
كيف تصلحه؟
دع نطاق الإنشاء الفعلي يملك التحرير.
كيف تتجنب تكراره؟
وثّق عمر النماذج المحقونة.

اختبر فهمك

1. هل يعيد المستودع نص عنصر مترجما مسبقا؟

اعرض الحل المشروح

أعد عادة قيم مجال أو حالات فشل منظمة. تنتمي الترجمة قرب سياسة العرض حيث تعرف اللغة الحالية وسياق الرسالة. حافظ على فئات خطأ مستقرة بين الطبقات وترجمها دون جعل شيفرة النقل تعتمد على شاشة.

2. كيف يثبت الاختبار منع التكرار أثناء التحميل؟

اعرض الحل المشروح

استخدم بديلا مزيفا يحوي Future مؤجلا وعداد استدعاءات. استدع load مرتين قبل حل الأولى وأكّد استدعاء المستودع مرة واحدة، ثم أكملها وتحقق من عودة busy إلى false وظهور التسميات المتوقعة. لا يلزم خادم حقيقي أو نوم زمني.

أهم ما تعلمته

  • افصل قرارات الواجهة عن الوصول للبيانات
  • اختبر النتائج المرصودة وسياسة الأوامر

المراجع الرسمية