نشرح ما هو Feature-Sliced Design — منهجية هندسة معيارية للواجهة الأمامية تعتمد على تقسيم المشروع حسب ميزات الأعمال بدلاً من الطبقات التقنية. على عكس الهندسة الطبقية الكلاسيكية (التحكمات، الخدمات، المستودعات)، تقوم FSD بتجميع الكود حسب الإمكانيات الوظيفية للتطبيق: كل ميزة تحتوي على منطقها الخاص وواجهة المستخدم والبيانات. وفقًا لاستطلاع State of Frontend 2024، يستخدم 23% من مطوري React منهجية FSD كمنهجية هندسية رئيسية، مما يجعلها الثانية من حيث الشعبية بعد هيكل Feature-based البحت.
النقاط الرئيسية
Feature-Sliced Design (FSD) هي منهجية هندسة تطبيقات الواجهة الأمامية اقترحتها لأول مرة في عام 2021 مجتمع feature-sliced.design. الفكرة الأساسية لـ FSD هي تجميع الكود حسب ميزات الأعمال (الشرائح)، كل منها وحدة مكتفية ذاتيًا: تحتوي على منطق الأعمال الخاص بها وواجهة المستخدم والتفاعل مع API ونماذج البيانات والاختبارات. هذا يميز FSD عن الهندسة الطبقية الكلاسيكية حيث يتم تقسيم الكود حسب المعايير التقنية (controller, service, repository).
تستعير المنهجية مفاهيم من Domain-Driven Design (DDD) و Bounded Context: كل ميزة في التطبيق هي bounded context منفصل بحدود واضحة. يجب ألا تؤدي التغييرات داخل ميزة واحدة إلى كسر الميزات الأخرى إذا كانت تستخدم فقط API العام للشريحة. وفقًا لاستطلاع State of Frontend 2024، تحتل FSD المرتبة الثانية من حيث الشعبية بين هندسات React (23%)، بعد الهيكل غير الرسمي Feature-based (31%).
في التطوير المحمول، تتكيف FSD مع خصوصيات وحدات Android وأطر iOS. في IT Sectr، نستخدم FSD للمشاريع التي تحتوي على 10+ شاشات و3+ فرق — تسمح المنهجية بتطوير الميزات بشكل مستقل وتقليل التعارضات في git بنسبة 40% مقارنة بالمستودع الأحادي دون حدود الشرائح.
تحدد FSD سبع طبقات هرمية، كل منها تحتوي على كود بمستوى تجريد معين. القاعدة الهندسية الرئيسية هي أن الطبقات يمكنها فقط استيراد الكود من الطبقات السفلية. يعتبر انتهاك هذه القاعدة (استيراد طبقة features في entities) خطأً هندسيًا ويتم منعه بواسطة أداة الفحص.
| الطبقة | الغرض | تستورد |
|---|---|---|
| app | تهيئة التطبيق، المزودون، الأنماط العامة، التوجيه | أي طبقات |
| processes | عمليات الأعمال التي تجمع عدة ميزات (الإعداد، الدفع) | pages, features, entities, shared |
| pages | تجميع الميزات في الصفحة، توجيه الصفحات | features, entities, shared |
| features | سيناريوهات المستخدم: نموذج تسجيل الدخول، قائمة المفضلة، فلتر البحث | entities, shared |
| entities | كيانات الأعمال: User, Product, Order, Cart | shared |
| widgets | مكونات واجهة مستخدم مركبة: Header, Sidebar, ArticleCard | shared, entities |
| shared | الأدوات المساعدة، UI-kit، عميل API، الإعدادات — مستقلة عن منطق الأعمال | المكتبات الخارجية فقط |
مثال على هيكل الدليل لمشروع FSD:
src/
├── app/ // طبقة التطبيق
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // الصفحات — تجميع الميزات
│ └── main/
├── features/ // الميزات — سيناريوهات المستخدم
│ ├── auth/ // شريحة «التفويض»
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // شريحة «قائمة المنتجات»
│ ├── ui/
│ └── model/
├── entities/ // كيانات الأعمال
│ ├── user/
│ └── product/
├── widgets/ // مكونات مركبة
│ └── header/
└── shared/ // أدوات مساعدة مشتركة وUI-kit
└── ui/قاعدة «الطبقات تنظر إلى الأسفل فقط» هي حجر الزاوية في FSD. إذا استورد feature authentity user — فهذا صحيح. إذا بدأ entity user في استيراد feature auth — فهذا اعتماد دائري وانتهاك للعزل. لضمان هذه القاعدة، يتم استخدام إضافات ESLint (eslint-plugin-fsd) أو أدات فحص مخصصة لواجهات API العامة للشرائح.
الشريحة (Slice) — وحدة التجميع الرئيسية في FSD، المقابلة لميزة أو كيان تجاري واحد. كل شريحة تقع داخل إحدى الطبقات السبع (features, entities, widgets, pages) وتحتوي على مجموعة كاملة من الكود لتنفيذ وظيفة محددة: مكونات واجهة المستخدم، نموذج البيانات، عميل API، الثوابت والاختبارات.
يتم تحديد حدود الشرائح حسب مجال الأعمال: feature auth تشمل كل ما يتعلق بالتفويض (نموذج تسجيل الدخول، نموذج التسجيل، إعادة تعيين كلمة المرور)؛ entity user يشمل نموذج User و UserRepository والتسلسل. يجب ألا تتداخل الحدود: إذا كانت feature auth تحتاج إلى بيانات المستخدم — فإنها تستورد entity user بدلاً من تكرار المنطق. في التطوير المحمول، غالبًا ما تتوافق شريحة FSD مع وحدة Gradle في Android أو حزمة Swift في iOS.
الشرائح معزولة بشكل صارم: الهيكل الداخلي لشريحة واحدة غير مرئي للشرائح الأخرى. للتفاعل بين الشرائح، يتم استخدام API عام — ملف index.ts/index.js الذي يصدر فقط ما هو مسموح باستخدامه خارجيًا. كل شيء آخر هو وحدات خاصة. يمنع هذا النهج التبعيات العرضية ويبسط إعادة الهيكلة: تغيير التنفيذ الخاص لشريحة واحدة لا يؤثر على الشرائح الأخرى.
داخل كل شريحة FSD، يتم تنظيم الكود أيضًا حسب القطاعات — فئات تقنية تتكرر عبر جميع الشرائح. تتضمن المجموعة القياسية من القطاعات ui (مكونات الواجهة)، model (منطق الأعمال، Store, Actions, Reducer)، api (طلبات الخادم، الطفرات)، lib (الأدوات المساعدة) و config (إعدادات الميزة).
| القطاع | المحتوى | مثال |
|---|---|---|
| ui/ | مكونات React/Vue/SwiftUI، الأنماط، Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, الأنواع، العقود | LoginStore.ts, authReducer.ts |
| api/ | عملاء HTTP، الطفرات، استدعاءات RPC | authApi.ts, loginMutation.ts |
| lib/ | وظائف مساعدة، مدققات | validateEmail.ts, formatPhone.ts |
| config/ | الثوابت، إعدادات الميزة | authConfig.ts, endpoints.ts |
القطاعات هي توصية وليست قاعدة صارمة. إذا كانت الشريحة صغيرة، يمكن دمج القطاعات. للشرائح الكبيرة (ميزة تحتوي على 10+ ملفات)، التقسيم إلى قطاعات إجباري — بدونه يتحول الهيكل الداخلي بسرعة إلى «سلة» من 50 ملفًا حيث يستغرق البحث عن المكون المطلوب دقائق. في التطوير المحمول، غالبًا ما يتم استبدال القطاعات بهيكل ملفات حسب النوع: كل ميزة هي ملف Swift منفصل أو فئة Kotlin بأنواع داخلية.
في التطوير المحمول، تتكيف FSD مع خصائص المنصة — الهيكل المعياري لـ Android (وحدات Gradle) و Swift Package Manager. التكيف مع Android يفترض أن كل شريحة هي وحدة Gradle منفصلة مع build.gradle الخاص بها. الوحدات feature-auth و feature-profile و entity-user و shared-ui معزولة عن بعضها البعض على مستوى البناء: feature-auth لا يمكنها استيراد feature-profile ما لم يتم تحديد ذلك في التبعيات.
التكيف مع iOS مبني على Swift Package Manager: كل شريحة هي حزمة Swift مع API عام. في مشاريع TCA، تحتوي شريحة feature.auth على Reducer و Store و View وعميل API خاص بها. وفقًا لاستطلاع Swift Community Survey 2024، يستخدم 28% من مشاريع iOS مع TCA هندسة شرائح قريبة من FSD.
المشكلة الرئيسية لتكيف FSD مع المحمول هي تكرار طبقة shared. في التطوير المحمول، تعتمد مكونات واجهة المستخدم (shared/ui) غالبًا على المنصة (Android Views مقابل Jetpack Compose مقابل SwiftUI)، مما يتطلب وحدات shared منفصلة لكل تقنية. في FSD، تكون طبقة shared عادةً مستقلة عن المنصة (أدوات مساعدة، إعدادات)، بينما يتم نقل UI-kit إلى وحدة منفصلة أو مكتبة مكونات.
مزايا FSD تصبح ملحوظة في المشاريع الكبيرة التي تضم 10+ مطورين. كل مطور أو فريق يعمل على شريحته الخاصة دون لمس كود الآخرين. تقل التعارضات في git بنسبة 40–60% (بيانات من دراسات حالة feature-sliced.design). تتم إضافة الميزات الجديدة دون خطر كسر الميزات الحالية، بشرط استخدام API العام للشرائح فقط. إعادة هيكلة ميزة واحدة لا تتطلب تغييرات في الأخرى — يكفي إعادة كتابة ui/model/api داخل شريحة واحدة مع الحفاظ على API العام.
| الجانب | FSD | Feature-based (بدون FSD) | الهندسة الطبقية |
|---|---|---|---|
| عزل الميزات | صارم | متوسط | ضعيف |
| التطوير المتوازي | 10+ فرق | 3–5 فرق | 1–2 فرق |
| إعادة الاستخدام بين المشاريع | نعم (حزم شرائح) | فقط عبر النسخ واللصق | عبر وحدات shared |
| حاجز الدخول | عالي | منخفض | متوسط |
| عزل Gradle (Android) | أصلي (وحدات) | أصلي (وحدات) | ضعيف |
عيوب FSD — التداخل المفرط للمشاريع الصغيرة. إذا كان التطبيق يتكون من 3–5 شاشات، فإن سبع طبقات وتقسيم داخل كل شريحة يخلق كودًا تنظيميًا أكثر من التطبيق نفسه. حاجز الدخول مرتفع: يقضي المطورون الجدد 2–4 أسابيع في تعلم المنهجية. أيضًا، FSD غير متوافق بشكل جيد مع النماذج الأولية السريعة — يتطلب النموذج الأولي استيرادات متكررة عبر الطبقات، وهي محظورة في FSD وتبطئ التكرارات.
يوصى بالبدء بهيكل Feature-based أبسط والترحيل إلى FSD عندما يتجاوز عدد الشاشات 20 ويتجاوز الفريق 5 مطورين.
الأسئلة الشائعة
الهندسة المعمارية Feature-based تجمع الكود حسب الميزات دون قواعد استيراد صارمة — يمكن لـ feature Auth استيراد feature Profile آخر دون قيود. FSD تضيف تسلسلًا هرميًا للطبقات وقاعدة «الطبقات تنظر إلى الأسفل فقط». في Feature-based، يمكن أن تكون entity و feature على نفس المستوى وتستورد كل منهما الأخرى؛ في FSD، entity تقع أسفل feature، و feature تستورد entity وليس العكس. Feature-based مناسبة للمشاريع الصغيرة، FSD للمشاريع الكبيرة.
عزل الشرائح يبسط الاختبارات الوحدوية — يتم اختبار كل شريحة بشكل مستقل عن طريق محاكاة تبعيات الطبقات السفلية. بالنسبة لـ feature auth، يكفي محاكاة entity user. تتحقق اختبارات التكامل من API العام للشريحة. في Android، تحتوي وحدة Gradle للميزة على دليل اختبار خاص بها مع اختبارات Reducer وعميل API وواجهة المستخدم (عبر Compose Test). في iOS، تتضمن حزمة الشريحة اختبارات لجميع القطاعات.
نعم، تتوافق FSD بشكل جيد مع Jetpack Compose، خاصة في مشاريع Android متعددة الوحدات. كل شريحة هي وحدة Gradle منفصلة مع API عام عبر التوجيه exported. تحتوي طبقة features على ميزات Composable (LoginFeature, ProductListFeature)، وتحتوي طبقة entities على فئات البيانات و Repository، وتحتوي shared على UI-kit (MaterialTheme-wrapper، مكونات مخصصة). يُوصى باستخدام FSD لمشاريع Compose الكبيرة التي تضم 5+ مطورين.
الطبقات الإجبارية هي app, shared, entities و features. الباقي (processes, pages, widgets) اختيارية وتُضاف حسب الحاجة. في التطوير المحمول، غالبًا ما يتم دمج طبقة pages مع توجيه التنقل، ويتم استبدال widgets بـ shared/ui-kit. عادةً لا تُستخدم العمليات (processes) في المشاريع المحمولة — دورها تؤديه طبقة المجال أو منطق الأعمال في ViewModel. الشيء الرئيسي هو اتباع قاعدة التسلسل الهرمي للاستيراد.
تستعير FSD من DDD مفهومي Bounded Context و Ubiquitous Language. كل شريحة تتوافق مع bounded context — حد داخله تكون المصطلحات ذات معنى لا لبس فيه. داخل الشريحة، يتم استخدام لغة موحدة (ubiquitous language)، مفهومة لكل من المطورين ومحللي الأعمال. على سبيل المثال، في شريحة auth، المصطلحات «تسجيل الدخول» و «كلمة المرور» و «الرمز المميز» لها نفس المعنى لجميع أعضاء الفريق، مما يقلل سوء الفهم بين المحللين والمطورين بنسبة 30–50%.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا