اكتشف الطريق وأنت تسير: تصميم البرمجيات في عصر الذكاء الاصطناعي
مقالة

اكتشف الطريق وأنت تسير: تصميم البرمجيات في عصر الذكاء الاصطناعي

أسامة الغانمي · 21 فبراير 2026

لا تحتاج إلى تصميم مثالي من البداية. تحتاج إلى اتجاه، وإلى استعداد لمواصلة التحسين حتى تتقارب الأشياء.

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

أسطورة التصميم المثالي المسبق

كل مشروع برمجي يبدأ بالطريقة نفسها: يرسم أحدهم مربعات على السبّورة ويعلن: «هذه هي البنية». وغالبًا ما يكثر الإيماء بالموافقة. وأحيانًا تظهر سبّورة ثانية.

ثم تبدأ البناء فعلًا، فيحضر الواقع دون دعوة.

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

الحقيقة القاسية هي: لا يمكنك أن تعرف الشكل الكامل لنظامك قبل أن تبني أجزاء منه. المتطلبات تكذب. المستخدمون يفاجئونك. والحجم الكبير يكشف أشياء لم يتوقعها أي مخطط.

وهذا لا بأس به. المشكلة ليست أن تصميمك كان خاطئًا. المشكلة هي أن تعامل التصميم الأول كأنه مقدّس.

اتساق نهائي، لكن لقاعدة شيفرتك

إن عملت مع الأنظمة الموزّعة فأنت تعرف مفهوم الاتساق النهائي (eventual consistency): قد تكون لدى العُقد المختلفة في النظام رؤى مختلفة للبيانات في لحظة معينة، لكن مع وقت كافٍ وتواصل كافٍ تتقارب كلها إلى الحالة نفسها.

تصميم برمجياتك يعمل بالطريقة نفسها.

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

الهدف ليس أن تصيب من أول مرة. الهدف أن تواصل الخطأ بقدر أقل.

سمّها التطوير بمبدأ «اكتشفها وأنت تسير» (FIAYG). ليست جذابة مثل TDD أو DDD، لكنها أصدق بكثير في وصف كيف تُبنى البرمجيات فعلًا.

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

كيف بنينا المدار (أو: قصة فوضى مثمرة)

المدار إطار تصريحي يحوّل مخططات آلات الحالة إلى تطبيقات متكاملة. ملف .orb واحد يصف كياناتك وسلوكياتك وواجهتك، ويولّد المترجم واجهة React أمامية تعمل، وخلفية Express، ونماذج قاعدة البيانات.

هذا ما هو عليه الآن. وهكذا وصلنا إليه.

المرحلة 1: المشروع الواحد

بدأ الأمر بسيطًا. كان لدينا مشروع واحد، عميل يحتاج إلى تطبيق أعمال يعتمد على عمليات CRUD بكثافة. كتبناه بيدنا بالطريقة المعتادة: مكوّنات React، ومسارات Express، وكيانات TypeORM. شيفرة نمطية في كل مكان.

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

لا بد من طريقة أفضل.

فجرّبنا شيئًا: ماذا لو وصفنا البيانات والسلوك في مخطط JSON، وولّدنا الشيفرة النمطية منه؟

كان الأمر خشنًا. المخطط بالكاد كان منظّمًا. والمولّد قالب نصي مع استدعاءات fs.writeFileSync. لكنه عمل. العميل كان سعيدًا. وأصبحنا نسلّم أسرع.

ما تعلّمناه: نسبة الـ 80% من كل تطبيق التي هي شيفرة نمطية يمكن وصفها تصريحيًا. أما الـ 20% الفريدة فهي ما تريد فعلًا أن تقضي وقتك فيه.

المرحلة 2: العميل الثاني يكسر كل شيء

كان للعميل الثاني متطلبات مختلفة. كان مولّدنا مرتبطًا بإحكام شديد بأنماط العميل الأول. كنا قد ثبّتنا افتراضات في كل مكان: اصطلاحات التسمية، وبنية الملفات، وتسلسل المكوّنات.

كان بإمكاننا أن نرقّعه. لكننا توقفنا وسألنا: كيف ستبدو نسخة عامة من هذا؟

هنا بدأت البنية تتبلور. أدخلنا مفهوم Orbitals، وحدات ميزات مكتفية بذاتها تجمع كيانًا (شكل البيانات)، وسمة (trait: سلوك على هيئة آلة حالة منتهية)، وصفحة (مسارًا). وفصلنا تعريف المخطط عن توليد الشيفرة.

ما تعلّمناه: في اللحظة التي تصبح فيها لديك حالة استخدام ثانية، تكشف تجريداتك عن نفسها. إن لم يتعمّم الشيء فلم يكن تجريدًا. كان مصادفة.

المرحلة 3: المستودع الواحد والقيود

مع ازدياد عدد المشاريع ازدادت الفوضى. كان لكل مشروع عميل نظام تصميمه الخاص، واختلافاته الخاصة في المكوّنات، وفكرته الخاصة عن شكل «الزر». كنا نصون عشر نكهات من المكوّن نفسه.

فأعدنا هيكلة كل شيء في مستودع واحد (monorepo) بقواعد صريحة:

  • المكوّنات الأساسية تعيش في @almadar/ui، مشتركة، ومرقّمة الإصدارات، ولا تُكرَّر أبدًا
  • أنظمة تصميم العملاء تعيش في projects/{name}/design-system/، توسّع الأساس ولا تستبدله
  • المترجم في orbital-rust/، مقدّس، لا يُعدَّل أبدًا دون نقاش
  • الشيفرة المولّدة تذهب إلى projects/{name}/app/، ولا تُحرَّر مباشرة

والأهم أننا أضفنا قيودًا. قواعد صارمة يرمّزها الفريق في ملف CLAUDE.md يجب أن يتبعها كل مطوّر (بشري أو ذكاء اصطناعي):

  • لا تستخدم عناصر HTML الخام أبدًا، استخدم دائمًا مكوّنات نظام التصميم
  • المخطط أولًا، عدّل ملف .orb وأعد الترجمة، ولا تلمس الشيفرة المولّدة
  • المترجم مقدّس، وإضافة قاعدة تتطلب موافقة صريحة

وفرضنا تلك القيود بـ إضافة ESLint مخصّصة (@almadar/eslint). ليست إرشادات اختيارية، بل أخطاء حقيقية تمنع خطّاف ما قبل الإيداع (pre-commit hook). لا تحذيرات مسموحة. بعض القواعد التي بنيناها:

القاعدةما الذي تلتقطه
no-raw-dom-elementsتمنع <div>, <span>, <button> وغيرها. استخدم VStack وTypography وButton بدلًا منها
no-as-anyتمنع تحويلات النوع as any. أصلح مشكلة النوع الحقيقية
no-import-generatedتمنع الاستيراد من projects/*/app/. الشيفرة المولّدة ليست واجهة برمجية
require-closed-circuit-propsيجب أن يقبل كل مكوّن className وisLoading وerror وentity
require-event-busيجب أن تستخدم التفاعلات useEventBus() لا onClick الخام
require-display-nameيجب أن يضبط كل مكوّن displayName لأغراض التصحيح
require-storiesيجب أن يُسلَّم كل مكوّن جديد مع ملف .stories.tsx
event-naming-conventionيجب أن تتبع أحداث الواجهة النمط UI:EVENT_NAME
template-no-hooksمكوّنات القوالب نقية. لا useState ولا useEffect
template-no-iterationالقوالب لا تكرّر. الكائن العضوي (organism) هو من يتولى التكرار
organism-no-callback-propsتتواصل الكائنات العضوية عبر ناقل الأحداث، لا عبر دوال الاستدعاء في الخصائص

يشغّل خطّاف ما قبل الإيداع ESLint على كل ملف .ts/.tsx في منطقة الإعداد. إن انطلقت أي قاعدة مُنع الإيداع. بلا استثناءات. كل قاعدة بمستوى الخطورة 2 (خطأ)، لا تحذيرًا. التحذيرات طموحات. أما الأخطاء فهي البنية.

والنتيجة: لا يستطيع مطوّر جديد، بشريًا كان أو ذكاءً اصطناعيًا، أن ينتهك مبادئ التصميم عن غير قصد. المدقّق يقول لا قبل أن يُفتح طلب الدمج أصلًا.

القيود تبدو مقيِّدة. لكنها في الحقيقة محرِّرة. حين تكون القواعد واضحة تصبح القرارات أسرع، وتُلتقط التناقضات أبكر، ويستطيع أعضاء الفريق الجدد المساهمة دون أن يكسروا شيئًا.

ما تعلّمناه: المستودع الواحد بلا قيود ليس سوى كتلة واحدة مهذّبة. القيود هي البنية، والتدقيق (linting) هو ما يجعلها حقيقية.

المرحلة 4: الذكاء الاصطناعي يغيّر القواعد

هنا يصبح الأمر مثيرًا.

حين وصلت مساعدات البرمجة بالذكاء الاصطناعي، تبيّن أن بنيتنا القائمة على القيود هي بالضبط ما تحتاجه لتعمل جيدًا. نموذج لغوي كبير (LLM) معه مخطط واضح ليحرّره، وسجل أنماط يتحقق منه، ومدقّق يمنع الأنماط السيئة، ومترجم يقول «لا» للمخرجات المعطوبة؟ هذا وكيل ذكاء اصطناعي منتج.

ونموذج لغوي كبير يعمل في قاعدة شيفرة حرّة بلا قواعد؟ هذا وكيل واثق جدًا يفعل الشيء الخطأ بثقة.

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

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

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

دليل FIAYG

إن كنت مبتدئًا، فهكذا تطبّق هذا دون أن تبني إطارًا من الصفر:

1. ابدأ ببساطة. ببساطة محرجة.

يجب أن تفعل نسختك الأولى شيئًا واحدًا. ليس الشيء مع معالجة الأخطاء مع التخزين المؤقت مع نظام إعدادات. الشيء فقط. ستتعلم من إطلاق شيء صغير أكثر مما تتعلم من تصميم شيء كبير.

2. لاحظ التكرار، إنه رسالة

حين تكتب الشيفرة نفسها للمرة الثالثة، فهذه قاعدة الشيفرة تخبرك أن شيئًا ما يريد أن يُجرَّد. لا تجرّد عند التكرار الأول (استعجال). ولا تتجاهل الثالث (إهمال). المرة الثانية هي الإشارة، والثالثة هي التأكيد.

3. رمّز ما تتعلمه على هيئة قيود

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

4. يجب أن تصبح بنيتك أصغر مع الوقت

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

5. لا تخشَ التحوّل

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

كيف يبدو التقارب

بعد عدة سنوات ومشاريع عملاء كثيرة، هذا ما تقاربنا إليه:

  • ملف مخطط واحد لكل مشروع، هو المصدر الوحيد للحقيقة
  • مترجم واحد، حتمي، يتحقق من أكثر من 50 قاعدة ويولّد كل الشيفرة النمطية
  • نظام تصميم واحد مع امتدادات لكل مشروع
  • إضافة ESLint مخصّصة واحدة، 17 قاعدة تُفرض على كل إيداع
  • مكتبة معيارية واحدة من السلوكيات القابلة لإعادة الاستخدام (CRUD، والمعالجات المتعددة الخطوات، والرئيسي-التفصيلي، والترقيم)
  • قيد واحد يتبعه كل مطوّر وكل وكيل ذكاء اصطناعي

الخلاصة

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

اكتشفها وأنت تسير. رمّز ما تتعلمه. واصل الخطأ بقدر أقل.

الاتساق نهائي. أطلق مع ذلك.

أسامة الغانمي

المعرفة حرية. ومن حق الناس أن يفهموا الأنظمة التي تحكمهم.

في أماكن أخرى
© 2026 أسامة الغانمي. ليوبليانا، سلوفينيا.