كان تحديث نظامنا القديم كابوساً: كيف أنقذنا نمط ‘التين الخانق’ من جحيم ‘إعادة البناء الكبرى’؟

السلام عليكم ورحمة الله وبركاته، معكم أخوكم أبو عمر.

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

وقف المدير التقني وقال جملته التي لا زالت ترن في أذني: “يا جماعة الخير، الحل الوحيد هو إعادة بناء كل شيء من الصفر. The Big Bang Rewrite!”. صمت رهيب عمّ الغرفة. إعادة البناء الكبرى؟ هذا يعني شهوراً، وربما سنوات، من العمل في الخفاء، دون أن يرى المستخدمون أي ميزة جديدة، مع مخاطرة هائلة بأن نفشل في النهاية ونخسر القديم والجديد. شعرت وقتها بغصة في حلقي، وقلت في نفسي: “هاي شغلانة ما بتخلص، ورح تفتح علينا أبواب جهنم”.

هذه القصة ليست فريدة، بل هي كابوس يعيشه الكثير من المطورين والشركات. لكن بفضل الله، وجدنا مخرجاً، مخرجاً استوحيناه من الطبيعة نفسها، وهو ما يعرف بـ “نمط التين الخانق” (Strangler Fig Pattern). في هذه المقالة، سأشارككم تجربتنا بالتفصيل، وكيف أنقذنا هذا النمط من قرار كان سيدمرنا.

ما هو جحيم “إعادة البناء الكبرى” (The Big Bang Rewrite)؟

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

  • مخاطرة عالية بالفشل: نسبة فشل هذه المشاريع مرتفعة جداً. قد تنفد الميزانية، أو يتغير فريق العمل، أو تظهر تعقيدات لم تكن في الحسبان.
  • زمن طويل بلا عائد: تخيل أنك تعمل لمدة سنة أو سنتين دون أن تقدم أي قيمة ملموسة للعمل أو للمستخدمين. خلال هذه الفترة، منافسوك يطلقون الميزات الجديدة وأنت لا تزال “تبني الأساسات”.
  • تغير المتطلبات: عالم الأعمال سريع. المتطلبات التي بدأت بها مشروع إعادة البناء ستكون قديمة بحلول وقت إطلاقه.
  • فقدان منطق العمل الخفي: الأنظمة القديمة، رغم عيوبها، تحتوي على سنوات من منطق العمل (Business Logic) المتراكم، بعضه غير موثق حتى. إعادة كتابة كل هذا من الذاكرة أو من الهندسة العكسية شبه مستحيل دون أخطاء.
  • معنويات الفريق: المشاريع الطويلة والمجهدة التي لا نهاية واضحة لها تقتل معنويات الفريق وتؤدي إلى الإرهاق والاحتراق الوظيفي.

باختصار، كما نقول بلهجتنا: “إنت بتطفي حريقة صغيرة ببنزين”. إعادة البناء الكبرى هي مخاطرة هائلة لا تستطيع معظم الشركات تحملها.

ظهور المنقذ: نمط التين الخانق (Strangler Fig Pattern)

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

“الفكرة هي بناء تطبيق جديد حول حواف التطبيق القديم، ومع مرور الوقت، ينمو التطبيق الجديد ليخنق ويستبدل التطبيق القديم في النهاية.” – مارتن فاولر

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

كيف طبقنا النمط خطوة بخطوة؟ (رحلتنا العملية)

الكلام النظري جميل، لكن “الحكي ما بطعمي خبز”. دعونا نرى كيف طبقنا هذا عملياً. نظامنا القديم كان تطبيق ويب ضخماً (Monolith) مسؤولاً عن كل شيء: إدارة المستخدمين، المنتجات، الطلبات، الفواتير، إلخ.

الخطوة الأولى: تحديد “الواجهة الخانقة” (The Strangler Façade)

أول وأهم خطوة هي وضع “حارس” على بوابة النظام القديم. هذا الحارس هو عبارة عن طبقة (غالباً بروكسي عكسي أو API Gateway) تتلقى كل الطلبات الموجهة للنظام. في البداية، وظيفة هذا الحارس هي فقط تمرير كل الطلبات كما هي إلى النظام القديم دون أي تغيير.

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


# nginx.conf
server {
    listen 80;
    server_name my-legacy-app.com;

    location / {
        # في البداية، كل الطلبات تذهب مباشرة إلى النظام القديم
        proxy_pass http://LEGACY_SYSTEM_IP:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

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

الخطوة الثانية: بناء أول خدمة جديدة (The First New Service)

هنا تكمن الحكمة. لم نبدأ بالجزء الأكثر تعقيداً، بل اخترنا جزءاً مستقلاً نسبياً وذا أهمية متوسطة. في حالتنا، كان “إدارة ملفات المستخدمين الشخصية” (User Profiles).

بنينا خدمة مصغرة (Microservice) جديدة باستخدام تقنيات حديثة (Node.js في حالتنا)، مع قاعدة بيانات خاصة بها. كانت هذه الخدمة مسؤولة فقط عن عرض وتعديل بيانات المستخدمين.

نصيحة من أبو عمر: لا تبدأ بالجزء الأصعب! ابدأ بشيء صغير تحقق فيه فوزاً سريعاً (quick win). هذا يرفع معنويات الفريق ويثبت للإدارة أنكم على الطريق الصحيح، ويعطيك الثقة للمتابعة.

الخطوة الثالثة: تحويل المسار (Intercept and Redirect)

بعد أن أصبحت الخدمة الجديدة جاهزة ومختبرة جيداً، عدنا إلى “الواجهة الخانقة” (Nginx) وقمنا بتعديل بسيط. أي طلب يأتي على المسار /api/users يجب أن يذهب الآن إلى الخدمة الجديدة، بينما بقية الطلبات تظل تذهب إلى النظام القديم.


# nginx.conf (بعد التحديث)
server {
    listen 80;
    server_name my-legacy-app.com;

    # الطلبات الخاصة بالملفات الشخصية تذهب الآن للخدمة الجديدة
    location /api/users {
        proxy_pass http://NEW_USER_SERVICE_IP:3000;
        # ... إعدادات البروكسي
    }

    # أي شيء آخر يظل على النظام القديم
    location / {
        proxy_pass http://LEGACY_SYSTEM_IP:8080;
        # ... إعدادات البروكسي
    }
}

كانت تلك لحظة فارقة. لأول مرة، جزء من نظامنا يعمل على البنية التحتية الجديدة والحديثة، والمستخدمون يتعاملون معه بشفافية تامة دون أن يشعروا بأي فرق. لقد “خنقنا” أول جزء من النظام القديم بنجاح!

الخطوة الرابعة: التكرار والخنق التدريجي (Iterate and Strangle)

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

  1. اختر وحدة أو ميزة من النظام القديم (مثلاً: إدارة المنتجات).
  2. ابنِ خدمة مصغرة جديدة لها.
  3. حدّث الواجهة الخانقة لتوجيه الطلبات الخاصة بهذه الميزة إلى الخدمة الجديدة.
  4. كرّر.

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

نصيحة من أبو عمر: كانت أكبر مشكلة واجهتنا هي قاعدة البيانات المتشابكة. الحل الذي اتبعناه هو بناء “طبقة مقاومة للفساد” (Anti-Corruption Layer). بمعنى آخر، بنينا واجهة برمجية (API) بسيطة فوق قاعدة البيانات القديمة، وبدلاً من أن تتصل الخدمات الجديدة مباشرة بقاعدة البيانات القديمة، كانت تتصل بهذه الواجهة. هذا سمح لنا بفصل الخدمات الجديدة تدريجياً عن تفاصيل وبنية قاعدة البيانات القديمة المعقدة.

متى يكون نمط التين الخانق هو الحل الأمثل (ومتى لا يكون)؟

هذا النمط ليس حلاً سحرياً لكل المشاكل. من المهم أن تعرف متى تستخدمه.

الحل الأمثل في الحالات التالية:

  • تحديث أنظمة الويب الضخمة والمتجذرة (Monolithic Web Applications).
  • عندما تكون مخاطر إعادة البناء الكبرى عالية جداً.
  • عندما تحتاج إلى الاستمرار في إضافة ميزات جديدة وتقديم قيمة للعمل أثناء عملية التحديث.
  • عندما يكون لديك نظام يمكن اعتراض الطلبات الموجهة إليه بسهولة عبر بروكسي أو بوابة.

قد لا يكون الحل الأمثل في الحالات التالية:

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

خلاصة تجربتي ونصائح من القلب 👨‍💻

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

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

والله ولي التوفيق.

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

أتمتة العمليات

كانت تقاريرنا اليومية تستهلك ساعات: كيف أنقذتنا ‘أتمتة العمليات الروبوتية’ (RPA) من جحيم النقرات المتكررة؟

قصتي الشخصية مع أتمتة التقارير اليومية التي كانت تسرق ساعات من وقت فريقنا. اكتشفوا معنا ما هي أتمتة العمليات الروبوتية (RPA)، وكيف يمكنها أن تحرركم...

28 مايو، 2026 قراءة المزيد
نصائح برمجية

كانت دوالنا وحوشًا من ألف سطر: كيف أنقذنا ‘استخلاص الدالة’ (Extract Method) من جحيم التعقيد؟

أشارككم قصة من أرض المعركة البرمجية، يوم واجهنا دالة عملاقة كادت أن تدمر مشروعنا. اكتشفوا كيف كانت تقنية "استخلاص الدالة" (Extract Method) البسيطة طوق النجاة...

28 مايو، 2026 قراءة المزيد
ذكاء اصطناعي

نماذجنا اللغوية كانت تهذي! كيف أنقذنا الذكاء الاصطناعي من الهلوسة بتقنية RAG؟

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

28 مايو، 2026 قراءة المزيد
تسويق رقمي

كانت حملاتنا تصرخ في الفراغ: كيف أنقذتنا ‘التجزئة الديناميكية بالتعلم الآلي’ من جحيم العروض غير الملائمة؟

بصفتي مبرمجًا، رأيت بأم عيني كيف تحترق ميزانيات التسويق بسبب العروض العامة. في هذه المقالة، أسرد لكم قصة حقيقية حول كيف انتقلنا من حملات تائهة...

28 مايو، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

كان تطبيقنا يستبعد 15% من المستخدمين بصمت: كيف أنقذتنا ‘إمكانية الوصول الرقمية’ (a11y) من كارثة التصميم؟

كنا نظن أن تطبيقنا ناجح، حتى اكتشفنا أننا كنا نستبعد 15% من مستخدمينا بصمت. هذه قصتي كـ 'أبو عمر' وكيف غيرت 'إمكانية الوصول الرقمية' (a11y)...

28 مايو، 2026 قراءة المزيد
برمجة وقواعد بيانات

ما وراء البحث التقليدي: كيف تُمكّن قواعد بيانات المتجهات تطبيقات الذكاء الاصطناعي من فهم المعنى؟

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

27 مايو، 2026 قراءة المزيد
البودكاست