لماذا تحتاج تطبيقاتنا إلى Clean Architecture أكثر من أي وقت مضى؟

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

وقد سلطت الضوء على هذا المفهوم المهندسة آية هزاع في جلسة مميزة قدمتها ضمن فعاليات Mobile Dev Meetups، التي أُقيمت في مركز سند – دمشق بتاريخ 11 كانون الثاني 2025، حيث ناقشت خلالها أهمية المعمارية النظيفة في دعم استدامة التطبيقات وتحقيق الجودة البرمجية على المدى الطويل.

الفهرس

  1. المعمارية (Architecture) والتصميم (Design) الفخ الذي يقع فيه العديد من المبرمجين
  2. عندما تتحول التعديلات البسيطة إلى أزمة كبيرة
  3. هل تكمن قيمة مشروعك في عمله اليوم أم في مرونته غدًا؟
  4. المعمارية النظيفة (Clean architecture)
  5. قواعد ثابتة… وأخرى تتغيّر: كيف نفصل بينهما؟
  6. هندسة بلا صداع: افصل التنفيذ عن المنطق!
  7. مبادئ المعمارية النظيفة  (Clean Architecture): أسس بناء الأنظمة القابلة للتعديل والصيانة
  8. الطبقات في المعمارية النظيفة (Clean Architecture)

محاور الجلسة

أولاً: المعمارية (Architecture) التصميم (Design) الفخ الذي يقع فيه العديد من المبرمجين

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

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

ما الفرق بين المعمارية والتصميم؟

  • المعمارية: (Architecture)
    هي الهيكل العام الذي يحدد كيفية توزيع مكونات النظام وتفاعلها مع بعضها. هي المخطط الشامل الذي يوجّه بناء النظام.
  • التصميم (Design) :
    هو الترجمة التفصيلية للمعمارية يتم فيه تحديد كيفية بناء كل جزء من النظام، وكيفية تواصله مع الأجزاء الأخرى.
  • أي أن المعمارية تعطيك الصورة العامة، بينما التصميم يحول تلك الصورة إلى تفاصيل قابلة للتنفيذ.

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

إذا غُفل أحد الجانبين، ستكون النتيجة بناء غير متناسق أو صعب التنفيذ

 لماذا من الضروري التمييز بين المعمارية والتصميم؟

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

ثانياً: عندما تتحول التعديلات البسيطة إلى أزمة كبيرة

عندما تبدأ ببناء تطبيق برمجي، ما الذي تركز عليه أولاً؟
هل تركز على ما سيراه المستخدم من واجهات وميزات؟ أم تفكر بما سيحدث لاحقاً عندما يُطلب تعديل أو إضافة ميزة جديدة؟

غالبًا ما يُوجه المبرمجون تركيزهم نحو السلوك  (Behavior): وهو ما يقدمه المشروع من وظائف وتجربة للمستخدم.
لكن في المقابل، يتم في كثير من الأحيان إهمال المعمارية: (Architecture)  وهي الأساس الذي يُبنى عليه المشروع،   والذي يحدد مدى سهولة تعديله وتطويره مستقبلاً.

تخيّل أن تعديلاً بسيطاً كنقل مكان زر في الواجهة يتطلب منك تعديل عشرات الملفات!
عندها ستدرك أهمية الدور الخفي للمعمارية الجيدة، وكم كان تجاهلها مكلفاً!

ثالثاً : هل تكمن قيمة مشروعك في عمله اليوم أم في مرونته غدًا؟

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

وهنا يبرز سؤال جوهري: هل من الممكن أن يصل مشروع ما إلى نقطة يصبح فيها التعديل مستحيلاً أو غير مجدٍ؟
في بعض الحالات، قد تتجاوز تكلفة التعديلات المطلوبة الفوائد المتوقعة منها، مما يجعل الاستمرار في المشروع غير منطقي من الناحية الاقتصادية. وعندها، يصبح المشروع غير قابل للاستدامة، ويكون مصيره التوقف أو إعادة البناء من الصفر.

رابعاً : المعمارية النظيفة (Clean architecture)

مبدأ الاعتمادية (Dependency Rule) وكيف يعمل ؟

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

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

يتكوّن المشروع عادةً من عدة دوائر:

  • لدائرة الداخلية  : (Core / Domain) وتضم منطق العمل الأساسي (Business Rules)؛ أي القواعد التي تحكم سلوك النظام. وهذه الطبقة يجب أن تبقى مستقلة تماماً عن التفاصيل الخارجية المتغيرة باستمرار كالتخزين أو العرض.
  • الدوائر الخارجية: مثل طبقة البيانات (Database) أو طبقة العرض (UI)، وهي الطبقات التي يمكنها الاستفادة من منطق النظام في الداخل، لكنها لا تؤثر عليه أو تغيّر بنيته.

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

خامساً : قواعد ثابتة… وأخرى تتغيّر .. كيف نفصل بينهما ؟

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

هناك قاعدتان اساسيتان:

  • القواعد المؤسسية الثابتة (Enterprise Business Rules): تُجسّدها الكيانات (Entities)، وهي تمثّل جوهر النظام، وتُعبّر عن القواعد العامة التي لا تتغيّر مهما اختلف التطبيق أو طريقة استخدامه.
    مثال: في نظام بنك، “لا يمكن أن يكون الرصيد سالباً ” قاعدة أساسية، يجب أن تُحترم في كل التطبيقات، سواء كانت تطبيقاً هاتفياً، أو نظاماً داخلياً للموظفين، أو موقعاً إلكترونياً.
  • القواعد خاصة بالتطبيق (Application Business Rules):
    تُجسّدها حالات الاستخدام (Use Cases)، حيث تمثّل ما يريد المستخدم فعله، وتتضمّن قواعد مرتبطة بطريقة تنفيذ هذه الأفعال داخل التطبيق ويمكن تعديلها أو تخصيصها بحسب السياق
    مثال: في نفس البنك، حالة “فتح حساب جديد” قد تتضمّن قاعدة مثل: “يجب رفع صورة الهوية إذا تم فتح الحساب عبر التطبيق”. هذه القاعدة تخص هذا التطبيق تحديداً، وقد تختلف في الفروع أو الأنظمة الأخرى.

هذا الفصل بين القواعد الثابتة والمتغيرة يتيح تطوير التطبيقات وتعديلها بسهولة، دون المساس بالبنية الأساسية للنظام.

سادساً : هندسة بلا صداع: افصل التنفيذ عن المنطق!

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

لحل هذه المشكلة، تأتي أهمية طبقة الواجهات التكيفية (Interface Adapters) تعمل هذه الطبقة كحلقة وصل ذكية، حيث تقوم بتحويل البيانات بين شكلين: الأول يتناسب مع المنطق الأساسي للنظام مثل الـ Use Cases وEntities، والثاني يتناسب مع الأنظمة الخارجية (مثل قاعدة البيانات أو الويب). بذلك، يبقى منطق العمل معزولاً عن تغيّرات الأنظمة الخارجية.

تعتمد هذه الطبقة على مبدأين أساسيين:

  • عكس الاعتمادية (Dependency Inversion) يضمن هذا المبدأ أن يعتمد النظام على الواجهات (Interfaces) بدلاً من التفاصيل الداخلية، مما يسهل التعديل والتطوير.
  • عزل منطق الأعمال (Business Logic Isolation): يُعزل منطق الأعمال عن التغيرات في الأنظمة الخارجية، مما يسمح بتحديث أو استبدال الأنظمة الخارجية دون التأثير على منطق العمل، مما يحافظ على استقرار النظام.

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

مثال: إذا تم تغيير قاعدة البيانات من MySQL إلى PostgreSQL أو تحديث واجهة المستخدم (UI)، فإن طبقة الواجهات التكيفية تقوم بتكييف البيانات (تعديل البيانات أو تحويلها إلى الصيغة المناسبة) بين النظام الجديد والقديم، مما يحافظ على منطق العمل الأساسي دون التأثير على وظائف النظام.

سابعاً : مبادئ المعمارية النظيفة (Clean Architecture) أسس بناء الأنظمة القابلة للتعديل والصيانة

  • فصل الاهتمامات (Separation of Concerns):
    كل طبقة لها مسؤولية محددة، مما يجعل النظام أسهل في الفهم والصيانة والاختبار.
  • عكس الاعتماد (Dependency Inversion):
    يجب ألا تعتمد الوحدات عالية المستوى على الوحدات منخفضة المستوى. يجب أن يعتمد كلاهما على التجريدات (مثل الواجهات).
    يضمن هذا المبدأ أن التغييرات في جزء من النظام لا تؤثر على أجزاء أخرى.
  • الاستقلالية عن الأطر (Independence from Frameworks):تم تصميم المعمارية لتكون مستقلة عن الأطر والمكتبات، مما يتيح لك استبدالها بأقل جهد ممكن.
  • قابلية الاختبار (Testability):من خلال عزل منطق الأعمال واستخدام الواجهات، تسهل الهندسة النظيفة كتابة اختبارات وحدات للمكونات الفردية

ثامناً : الطبقات في المعمارية النظيفة (Clean Architecture)

تعالج هذه الطبقة واجهة المستخدم وكل ما يتعلق بتفاعل المستخدم مع النظام. تشمل عناصر مثل الشاشات، الواجهات الرسومية (UI)، والمكونات التي تُظهر البيانات وتستقبل الإدخال.

طبقة البيانات (Data Layer) :

 تتمثل المهمة الأساسية في توفير البيانات للتطبيق، سواء من مصادر خارجية أو داخلية
تتضمن هذه الطبقة  تتألف من :

  • مصدر البيانات (Data Source):
    مسؤول عن جلب البيانات من واجهات برمجة التطبيقات (APIs)، قواعد البيانات، التخزين المحلي أو خدمات خارجية.
  • النموذج (Model):
    يُعرّف شكل البيانات كما يتم تبادلها مع المصادر، ويُستخدم لتحويل البيانات من وإلى التنسيقات المناسبة.
  • المستودع (Repository):
    يُعتبر نقطة الوصول المركزية للبيانات، حيث يطبّق المنطق الخاص بجلب، حفظ، ومعالجة البيانات.يقوم بتنفيذ ما تطلبه واجهات المستودعات في طبقة النطاق (Domain)، مع الحفاظ على فصل واضح بين منطق الأعمال ومصادر البيانات.

طبقة النطاق / المجال (Domain Layer) :

تُمثل هذه الطبقة قلب النظام وتحتوي على منطق الأعمال الأساسي (business logic) و تعتمد على مبدأ “الاعتماد على التجريدات وليس على التفاصيل” ( اي لا تهتم كيف تتم الأمور، بل تعتمد على ما الذي يجب أن يتم فقط)، وهنا يأتي دور ثلاث مفاهيم رئيسية

  • المستودع (Repository)  :
     هو واجهة (interface) تحدد  كيف نتعامل مع البيانات، دون الاهتمام بكيفية التنفيذ. أي أنها تصف ما يجب أن نفعله، مثل جلب منتج أو إضافته، بينما يُترك التنفيذ الفعلي لطبقة البيانات. بهذه الطريقة، نبقي منطق العمل منفصلاً عن تفاصيل التخزين، مما يجعل النظام أكثر مرونة وأسهل في التغيير.
  • حالة الاستخدام (Use Case) :
    يمثل منطق العمل الأساسي، فهو المسؤول عن تنفيذ القواعد الخاصة بالنظام. على سبيل المثال، “إضافة منتج” أو “حذف منتج”. لكن لا نحتاج إلى واجهات مجردة له، لأنه يقوم بمهمة واحدة محددة، بعكس المستودع الذي يحتوي عدة وظائف.
  • الكيان (Entity) :
    وهو نموذج البيانات الذي نستخدمه داخل النظام، ويحتوي فقط على المعلومات التي نحتاجها فعلاً. يختلف عن الـ Model الذي يعكس البيانات التي تأتي من المصدر الخارجي. نستخدم الـ Entity غالباً في طبقة العرض لأنه يمثل البيانات بشكل أنظف وأوضح.

طبقة العرض (Presentation Layer) :

  • عناصر الواجهة (Views):
    تشكل واجهة المستخدم التي يراها ويتفاعل معها المستخدم، مثل الشاشات والأزرار والنصوص.
    في تطبيقات Flutter، يتم إنشاء هذه العناصر باستخدام Widgets تمثل كل مكون من مكونات الواجهة.
  • إدارة الحالة (State Management):
    تُعنى بتتبع حالة التطبيق وتحديث واجهة المستخدم بناءً على أي تغييرات تحدث.
    تتوفر عدة أدوات في Flutter لإدارة الحالة بكفاءة، من أبرزها: Provider، Bloc، وRiverpod.

الختام

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

ألبوم الصور


اكتشاف المزيد من Mobile Dev Meetup

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

One Comment Add yours

  1. يقول mahmoudkok:

    Excellent piece on Clean Architecture. Clearly and concisely outlines its core principles and benefits for building robust, maintainable software. Highly recommended.

اترك رداً على mahmoudkokإلغاء الرد