Claude Code لتكرار واجهات Flutter: حلقة عملية لتحويل قصص المستخدم إلى شجرات ويدجت، حالة، وتنقل، مع الحفاظ على التغييرات مُجزّأة وسهلة المراجعة.

العمل السريع على واجهات Flutter غالبًا ما يبدأ بشكل جيد. تُعدّل تخطيطًا، تضيف زرًا، تنقل حقلًا، وتبدو الشاشة أفضل بسرعة. المشكلة تظهر بعد عدة جولات، عندما يتحوّل السرعة إلى مجموعة تغييرات لا يريد أحد مراجعتها.
الفرق يتكرر عادةً بنفس الأخطاء:
سبب كبير هو نهج "المطلب الكبير الواحد": وصف الميزة كاملةً، طلب مجموعة الشاشات كاملة، وقبول مخرج ضخم. يحاول المساعد المساعدة، لكنه يلمس أجزاء كثيرة من الشيفرة دفعة واحدة. هذا يجعل التغييرات فوضوية، صعبة المراجعة، وخطيرة للدمج.
حل قابل للتكرار يصلح ذلك عبر فرض الوضوح وتقليل نصف القطر المتأثر. بدلًا من "بناء الميزة بالكامل"، افعل مرارًا وتكرارًا: اختر قصة مستخدم واحدة، ولّد أصغر شريحة واجهة تُثبِت الفكرة، أضف فقط الحالة اللازمة لتلك الشريحة، ثم اربط التنقل لمسار واحد. كل تمريرة تبقى صغيرة بما يكفي للمراجعة، والأخطاء سهلة التراجع.
الهدف هنا هو سير عمل عملي لتحويل قصص المستخدم إلى شاشات ملموسة، معالجة الحالة، وتدفقات التنقل دون فقدان السيطرة. عند التنفيذ الجيد، تحصل على قطع واجهة مُجزّأة، فروق أصغر، ومفاجآت أقل عند تغيير المتطلبات.
قصص المستخدم مكتوبة للبشر، ليست لأشجار الودجت. قبل أن تولّد أي شيء، حوّل القصة إلى مواصفة واجهة صغيرة تصف السلوك المرئي. يجب أن يكون "مكتملًا" قابلًا للاختبار: ما الذي يمكن للمستخدم رؤيته، النقر عليه، وتأكيده — لا ما إذا كان التصميم "يبدو عصريًا".
طريقة بسيطة للحفاظ على النطاق واضحة هي تقسيم القصة إلى أربع فئات:
إذا بقيت القصة غامضة، أجب عن هذه الأسئلة بلغة بسيطة:
أضف القيود مبكرًا لأنها توجه كل قرار تصميمي: أساسيات الثيم (الألوان، المسافات، الطباعة)، الاستجابة (هاتف بوضع عمودي أولًا، ثم أحجام اللوح)، وحد أدنى من الوصولية مثل حجم هدف النقر، مقاييس النص المقروءة، وتسميات معنوية للأيقونات.
أخيرًا، حدد ما هو ثابت مقابل ما هو مرن حتى لا تثير الفوضى في قاعدة الشيفرة. العناصر الثابتة هي ما تعتمد عليها ميزات أخرى، مثل أسماء المسارات، نماذج البيانات، وواجهات الـ API الحالية. الأشياء المرنة أكثر أمانًا للتكرار مثل بنية التخطيط، نصوص المايكرو، والتكوين الدقيق للويدجت.
مثال: "بصفتي مستخدمًا، أستطيع حفظ عنصر إلى المفضلات من شاشة التفاصيل." مواصفة واجهة قابلة للبناء يمكن أن تكون:
هذا يكفي للبناء، المراجعة، والتكرار دون تخمين.
الفروق الصغيرة لا تعني العمل ببطء. تجعل كل تغيير واجهة سهل المراجعة، سهل التراجع، وصعب الكسر. القاعدة الأبسط: شاشة واحدة أو تفاعل واحد لكل تكرار.
اختر شريحة ضيقة قبل البدء. "أضف حالة فراغ لشاشة الطلبيات" شريحة جيدة. "إعادة تصميم كل تدفق الطلبيات" ليست كذلك. استهدف فرقًا يمكن لزميل أن يفهمه في دقيقة.
بنية مجلدات مستقرة تساعد أيضًا على الحفاظ على التغييرات محصورة. تخطيط بسيط يركّز على الميزة يمنعك من تبعثر الويدجتات والمسارات عبر التطبيق:
lib/
features/
orders/
screens/
widgets/
state/
routes.dart
حافظ على الويدجتات صغيرة ومركبة. عندما يكون للويدجت مدخلات ومخرجات واضحة، يمكنك تغيير التخطيط دون المساس بالمنطق، وتغيير الحالة دون إعادة كتابة الواجهة. فضّل الويدجتات التي تأخذ قيمًا بسيطة وردود نداء، لا حالة عالمية.
حَلقة تظل قابلة للمراجعة:
اجعل قاعدة صارمة: كل تغيير يجب أن يكون سهل التراجع أو العزل. تجنّب إصلاحات عابرة أثناء التكرار على شاشة. إذا لاحظت مشاكل غير ذات صلة، دوّنها وأصلحها في التزام منفصل.
إذا كانت أدواتك تدعم اللقطات والتراجع، استعمل كل شريحة كنقطة لقطة. بعض منصات vibes-coding مثل Koder.ai تتضمن لقطات وتراجع، مما يجعل التجربة أكثر أمانًا عند تجربة تغيير جريء في الواجهة.
عادة مفيدة أخرى تبقي التكرارات المبكرة هادئة: فضّل إضافة ويدجتات جديدة بدلاً من تعديل المشتركة. المكونات المشتركة هي المكان الذي تتحول فيه التغييرات الصغيرة إلى فروق كبيرة.
العمل السريع على الواجهة يظل آمنًا عندما تفصل التفكير عن الطباعة. ابدأ بخطة شجرة ويدجت واضحة قبل توليد الكود.
اطلب مخطط شجرة ويدجت فقط. تريده بأسماء الويدجتات، التدرّج، وماذا يعرض كل جزء. لا كود بعد. هنا تكتشف الحالات المفقودة، الشاشات الفارغة، وخيارات تخطيط غريبة بينما كل شيء ما يزال رخيصًا للتغيير.
اطلب تحليل مكونات مع المسؤوليات. اجعل كل ويدجت مركزة: ويدجت واحد يعرض الهيدر، آخر يعرض القائمة، وآخر يتعامل مع الفراغ/الخطأ. إذا احتاج شيء للحالة لاحقًا، دوّنه الآن لكن لا تنفذه بعد.
ولّد سقالة الشاشة والويدجتات الستاتلس. ابدأ بملف شاشة واحد بمحتوى نائب وتعليقات TODO واضحة. حافظ على المدخلات صريحة (معاملات الكونستركتور) حتى تتمكن من توصيل الحالة الحقيقية لاحقًا دون إعادة كتابة الشجرة.
قم بمرور منفصل لتفاصيل الأنماط والتخطيط: التباعد، الطباعة، الثيم، والسلوك الاستجابي. عامل التنسيق كفرق منفصل حتى تبقى المراجعات بسيطة.
ضع القيود مقدمًا حتى لا يخترع المساعد واجهة لا يمكنك شحنها:
مثال ملموس: القصة "بصفتي مستخدمًا، أستطيع مراجعة العناصر المحفوظة وإزالة واحد." اطلب شجرة ويدجت تتضمن AppBar، قائمة بسطور العناصر، وحالة فراغ. ثم اطلب تحليلًا مثل SavedItemsScreen, SavedItemTile, EmptySavedItems. فقط بعد ذلك، ولّد السقالة مع ويدجتات ستاتلس وبيانات تجريبية، وأخيرًا أضف التنسيق (فاصل، تباعد، زر إزالة واضح) في تمريرة منفصلة.
يتفكك تكرار الواجهة عندما يبدأ كل ويدجت باتخاذ القرارات. اجعل شجرة الويدجت غبية: تقرأ الحالة وتعرضها، لا تحتوي قواعد عمل.
ابدأ بتسمية الحالات بلغة بسيطة. معظم الميزات تحتاج لأكثر من "تحميل" و"تم":
ثم أدرج الأحداث التي تغير الحالة: نقرات، إرسال نموذج، سحب للتحديث، عودة، إعادة المحاولة، و"المستخدم حرر حقلًا". كتابة ذلك مقدمًا تمنع التخمين لاحقًا.
اختر نهج حالة واحد للميزة والتزم به. الهدف ليس "أفضل نمط" بل فروق متناسقة.
لشاشة صغيرة، عادةً يكفي كونترولر بسيط (مثل ChangeNotifier أو ValueNotifier). ضَع المنطق في مكان واحد:
قبل إضافة الكود، اكتب انتقالات الحالة بعبارات بسيطة. مثال لشاشة تسجيل الدخول:
"عند نقر المستخدم على تسجيل الدخول: ضع الحالة على تحميل. إذا البريد غير صالح: ابقَ في إدخال جزئي وأرِ رسالة داخلية. إذا كانت كلمة المرور خاطئة: ضع حالة خطأ مع رسالة وفعل إعادة المحاولة. إذا نجحت: ضع حالة نجاح وانتقل إلى الشاشة الرئيسية."
ثم ولّد أقل كود Dart يطابق تلك الجمل. تبقى المراجعات بسيطة لأنك تقارن الفارق مع القواعد المكتوبة.
اجعل التحقق صريحًا. قرّر ماذا يحدث عند المدخلات غير الصالحة:
عندما تُكتب هذه الإجابات، تبقى واجهتك نظيفة وكود الحالة صغيرًا.
الملاحة الجيدة تبدأ كخريطة صغيرة، لا ككومة مسارات. لكل قصة مستخدم، اكتب أربع لحظات: من أين يدخل المستخدم، الخطوة الأكثر احتمالًا التالية، كيف يلغون، وماذا يعني "العودة" (العودة للشاشة السابقة أو العودة إلى حالة منزلية آمنة).
خريطة مسارات بسيطة يجب أن تجيب عن الأسئلة التي عادةً تسبب إعادة عمل:
ثم حدد المعاملات الممررة بين الشاشات. كن صريحًا: معرّفات (productId, orderId)، فلاتر (نطاق التاريخ، الحالة)، وبيانات المسودة (نموذج معبأ جزئيًا). إذا تجاهلت هذا، ستنتهي بوضع الحالة في singletons عالمية أو إعادة بناء الشاشات "للعثور" على السياق.
الروابط العميقة مهمة حتى لو لم تشحنها في اليوم الأول. قرّر ماذا يحدث عندما تهبط مستخدم منتصف التدفق: هل تستطيع تحميل البيانات المفقودة، أو يجب إعادة التوجيه إلى شاشة دخول آمنة؟
كما قرّر أي الشاشات تعيد نتائج. مثال: شاشة "اختيار عنوان" تعيد addressId، وشاشة الدفع تحدّث دون إعادة تحميل كاملة. احتفظ بشكل النتيجة صغيرًا ومُنوّعًا حتى تبقى التغييرات سهلة المراجعة.
قبل الترميز، اذكر الحالات الحديّة: تغييرات غير محفوظة (أظهر حوار تأكيد)، مطلوب مصادقة (وقّف واستأنف بعد تسجيل الدخول)، والبيانات المفقودة أو المحذوفة (أظهر خطأ وطريقة خروج واضحة).
عندما تتكرر بسرعة، الخطر الحقيقي ليس "واجهة خاطئة"، بل واجهة لا يمكن مراجعتها. إذا لم يستطع الزميل أن يعرف ماذا تغيّر، لماذا تغيّر، وما الذي بقي ثابتًا، يصبح كل تكرار لاحق أبطأ.
قاعدة تساعد: ثبّت الواجهات أولًا، ثم اسمح بتحريك الباطن. ثبّت خواص الودجت العامة (المدخلات)، نماذج واجهة صغيرة، ووسائط المسارات. بعد تسمية ذلك وتكوينه، يمكنك إعادة تشكيل شجرة الودجت دون كسر بقية التطبيق.
اطلب خطة صديقة للاختلاف قبل توليد الكود. تريد خطة تقول أي الملفات ستتغير وأيها تبقى دون لمس. هذا يحفظ المراجعات مركّزة ويمنع الإصلاحات العرضية التي تغيّر السلوك.
أنماط تحافظ على فروق صغيرة:
افترض القصة "بصفتي متسوقًا، أستطيع تعديل عنوان الشحن من صفحة الدفع." ثبّت وسيط المسار أولًا: CheckoutArgs(cartId, shippingAddressId) يبقى ثابتًا. ثم كرّر داخل الشاشة. عندما يستقر التخطيط، قسمه إلى AddressForm, AddressSummary, وSaveBar.
إذا تغيّر التعامل مع الحالة (مثلاً، انتقلت التحقق من الودجت إلى CheckoutController)، تبقى المراجعة مقروءة: ملفات الواجهة تتغير عرضيًا لعرضها، بينما يظهر الكونترولر التغيير المنطقي في مكان واحد.
أسرع طريقة للإبطاء هي أن تطلب من المساعد تغيير كل شيء مرة واحدة. إذا لَمسة التزامن الواحد التخطيط، الحالة، والتنقل، فلن يعرف المراجعون ماذا أدى للخلل، ويصبح التراجع فوضويًا.
عادةً ما تكون عادة أكثر أمانًا: نية واحدة لكل تكرار — شكّل شجرة الودجت، ثم درّج الحالة، ثم وصل التنقل.
مشكلة شائعة السماح للكود المُولَّد باختراع نمط جديد في كل صفحة. إذا استخدمت صفحة Provider، والثانية setState، والثالثة أدخلت كونترولر مخصص، يصبح التطبيق غير متناسق بسرعة. اختر مجموعة صغيرة من الأنماط وطبّقها.
خطأ آخر هو وضع العمل غير المتزامن مباشرة داخل build(). قد يبدو مناسبًا في عرض سريع، لكنه يسبب استدعاءات متكررة عند إعادة البناء، وفلاشات، وأخطاء يصعب تتبعها. انقل الاستدعاء إلى initState(), view model، أو كونترولر مخصص، وخَلِّي build() للعرض.
التسمية فخ هادئ. الكود الذي يترجم لكنه يقرأ كـ Widget1, data2, أو temp يجعل عمليات إعادة التصميم المستقبلية مؤلمة. الأسماء الواضحة تساعد المساعد في إنتاج تغييرات متابعة أفضل لأن النية تصبح واضحة.
ضوابط تمنع الأسوأ:
build()تصحيح بصري كلاسيكي هو إضافة Container, Padding, Align, وSizedBox حتى يبدو الشيء مناسبًا. بعد عدة تمريرات، تصبح الشجرة غير قابلة للقراءة.
إذا كان زر غير محاذٍ، جرّب أولًا إزالة الأغلفة، استخدام حاوية تخطيط أب بسيطة، أو استخراج ويدجت صغيرة بقيودها الخاصة.
مثال: شاشة الدفع حيث يقفز إجمالي السعر أثناء التحميل. قد يقترح المساعد غلافًا أكثر لـ"تثبيت" الصف. حل أنظف هو تخصيص مساحة مؤقتة بمحدد تحميل بسيط مع الحفاظ على بنية الصف دون تغيير.
قبل الالتزام، قم بمرور لمدة دقيقتين يتحقق من قيمة المستخدم ويحميك من انحدارات مفاجئة. الهدف ليس الكمال، بل التأكد أن التكرار سهل المراجعة، سهل الاختبار، وسهل التراجع.
اقرأ قصة المستخدم مرة، ثم تحقق من هذه البنود ضد التطبيق المشغّل (أو على الأقل اختبار ويدجت بسيط):
فحص واقع سريع: إذا أضفت شاشة تفاصيل أمر جديدة، يجب أن تكون قادرًا على (1) فتحها من القائمة، (2) رؤية مؤشر تحميل، (3) محاكاة خطأ، (4) رؤية أمر فارغ، و(5) الضغط على العودة للعودة للقائمة دون قفزات غريبة.
إذا يدعم سير عملك اللقطات والتراجع، خُذ لقطة قبل تغييرات تخطيط أكبر. بعض المنصات مثل Koder.ai تدعم ذلك ويمكن أن تساعدك على التكرار أسرع دون تعريض الفرع الرئيسي للخطر.
قصة المستخدم: "بصفتي متسوقًا، أستطيع تصفح العناصر، فتح صفحة التفاصيل، حفظ عنصر للمفضلات، ومشاهدة المفضلات لاحقًا." الهدف الانتقال من الكلمات إلى الشاشات في ثلاث خطوات صغيرة قابلة للمراجعة.
التكرار 1: ركّز فقط على شاشة التصفح. أنشئ شجرة ويدجت كافية للعرض لكن غير مرتبطة ببيانات حقيقية: Scaffold مع AppBar, ListView من صفوف نائبة، وواجهة واضحة للتحميل والفراغ. احتفظ بالحالة بسيطة: تحميل (يعرض CircularProgressIndicator)، فراغ (رسالة قصيرة وربما زر حاول مرة أخرى)، وجاهز (يعرض القائمة).
التكرار 2: أضِف شاشة التفاصيل والتنقل. اجعلها صريحة: onTap تدفع مسارًا وتمرر كائن معلمات صغير (مثال: item id, title). ابدأ صفحة التفاصيل للعرض فقط بعنوان، وصف نائب، وزر إجراء "مفضلة". الهدف مطابقة القصة: قائمة -> تفاصيل -> رجوع، دون تدفقات إضافية.
التكرار 3: أدخل تحديثات حالة المفضلات وردود الفعل المرئية. أضف مصدر حقائق واحد للمفضلات (حتى لو كان في الذاكرة)، واربطه بالشاشتين. النقر على المفضلة يحدث الأيقونة فورًا ويعرض تأكيدًا صغيرًا (مثل SnackBar). ثم أضِف شاشة المفضلات التي تقرأ نفس الحالة وتتعامل مع حالة الفراغ.
فارق قابل للمراجعة عادةً يبدو هكذا:
browse_list_screen.dart: شجرة الودجت بالإضافة إلى واجهات التحميل/الفراغ/الجاهزitem_details_screen.dart: تخطيط الواجهة ويقبل معلمات التنقلfavorites_store.dart: حامل حالة بسيط وطرق التحديثapp_routes.dart: المسارات ومساعدي التنقل المطبوعين نوعيًاfavorites_screen.dart: يقرأ الحالة ويعرض فراغ/قائمةإذا أصبح أي ملف "مكان كل شيء يحدث فيه"، قسمه قبل المتابعة. الملفات الصغيرة ذات الأسماء الواضحة تبقي التكرار التالي سريعًا وآمنًا.
إذا كان سير العمل ينجح فقط عندما تكون "في الزون"، سينهار حين تغير الشاشة أو يلمسه زميل. اجعل الحلقة عادة بكتابتها ووضع ضوابط حول حجم التغيير.
استخدم قالب فريق واحد حتى تبدأ كل تكرار بنفس المدخلات وتنتج نفس نوع الناتج. ابقه قصيرًا لكن محددًا:
هذا يقلل من احتمال اختراع المساعد لأنماط جديدة منتصف الميزة.
اختر تعريفًا لـ"صغير" يسهل تطبيقه في مراجعة الكود. على سبيل المثال، قِد كل تكرار بعدد محدود من الملفات، وافصل إصلاحات الواجهة عن تغييرات السلوك.
مجموعة قواعد بسيطة:
أضِف نقاط فحص لتتمكن من التراجع عن خطوة سيئة بسرعة. على الأقل، وسم الالتزامات أو احتفظ بنقاط فحص محلية قبل عمليات إعادة تصميم كبيرة. إذا كان سير العمل يدعم لقطات وتراجع، استعملها بكثافة.
إذا أردت سير عمل مبني على الدردشة يمكنه توليد وتحسين تطبيقات Flutter نهاية إلى نهاية، فـKoder.ai يتضمن وضع تخطيط يساعدك على مراجعة الخطة والتغييرات المتوقعة قبل تطبيقها.
استخدم مواصفة واجهة صغيرة وقابلة للاختبار أولًا. اكتب 3–6 سطور تغطي:
ثم بنِ فقط تلك الشريحة (غالبًا شاشة واحدة + 1–2 ويدجت).
حوّل القصة إلى أربعة أقسام:
إذا لم تستطع وصف معيار القبول بسرعة، فالقصة ما تزال غامضة للتعديل النظيف.
ابدأ بتوليد مخطط شجرة ويدجت فقط (أسماء + هيكلية + ماذا يعرض كل جزء). لا تطلب كودًا بعد.\
ثم اطلب تحليل مسؤوليات المكونات (ماذا يمتلك كل ويدجت).\
فقط بعد ذلك، ولّد السقالة الستاتلس مع مداخل واضحة (قيم + ردود النداء)، وتعامل مع التنسيق في مرور منفصل.
اعتبرها قاعدة صارمة: نية واحدة لكل تكرار.\
إذا غيّر التزامن الواحد التخطيط والحالة والمسارات معًا، فلن يعرف المراجعون سبب الخطأ، وسيصعب التراجع.
خَلي الودجتات "غبية": يجب أن تعرض الحالة، لا أن تقرر قواعد الأعمال.\
افتراض عملي افتراضي:\
تجنب وضع استدعاءات غير متزامنة داخل build()—فهي تؤدي إلى استدعاءات متكررة عند إعادة البناء.
حدّد الحالات والانتقالات بكلمات بسيطة قبل الترميز.\
مثال نموذجي:
ثم أدرج الأحداث التي تنتقل بينها (تحديث، إعادة محاولة، إرسال، تحرير). يصبح الكود أسهل للمقارنة مع القواعد المدوّنة.
اكتب خريطة تدفق صغيرة للقصة:
افترِض بنية مجلدات مرتبة بحسب الميزة حتى تظل التغييرات محصورة. على سبيل المثال:
lib/features/<feature>/screens/lib/features/<feature>/widgets/lib/features/<feature>/state/lib/features/<feature>/routes.dartبعدها ركّز كل تكرار على مجلد ميزة واحد وتجنّب إصلاحات جانبية عشوائية في أماكن أخرى.
قاعدة بسيطة: ثبّت الواجهات العامة، وليس الباطن.\
المراجعون يهتمون أكثر بأن المدخلات/المخرجات بقيت ثابتة حتى لو تغيّر التخطيط.
قم بمرور سريع من دقيقتين:\
إذا كان نظامك يدعم لقطات/التراجع، فالتقط لقطة قبل أي إعادة تصميم كبيرة لتتمكن من التراجع بسهولة.
وثبّت ما الذي يُنقل بين الشاشات (IDs، فلاتر، بيانات مسودة) حتى لا تنتهي بوضع السياق في وحوش عالمية.