تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
يُعرف المشروع الذي يتضمّن وحدات Gradle متعددة باسم مشروع متعدد الوحدات. يشمل هذا الدليل أفضل الممارسات والأنماط المقترَحة لتطوير تطبيقات Android متعددة الوحدات.
مشكلة قاعدة الرموز المتزايدة
في قاعدة رموز متزايدة باستمرار، غالبًا ما تنخفض قابلية التوسّع وإمكانية القراءة وجودة الرموز بشكل عام بمرور الوقت. ويحدث ذلك نتيجة زيادة حجم قاعدة الرموز بدون اتّخاذ المسؤولين عن صيانتها إجراءات نشطة لفرض بنية تسهل صيانتها. تُعد عملية التقسيم إلى وحدات وسيلة لتنظيم قاعدة الرموز البرمجية بطريقة تحسّن إمكانية الصيانة وتساعد في تجنُّب هذه المشاكل.
ما هي عملية التقسيم إلى وحدات؟
التقسيم إلى وحدات هو ممارسة لتنظيم قاعدة رموز برمجية إلى أجزاء غير مرتبطة بإحكام ومستقلة. كل جزء هو وحدة. كل وحدة مستقلة وتخدم غرضًا واضحًا. من خلال تقسيم المشكلة إلى مشاكل فرعية أصغر وأسهل في الحل، يمكنك تقليل تعقيد تصميم نظام كبير وصيانته.
الشكل 1: الرسم البياني للعناصر التابعة في نموذج قاعدة رموز برمجية متعددة الوحدات
مزايا التقسيم إلى وحدات
تتعدّد مزايا تقسيم التطبيق إلى وحدات، ولكن يتركّز كل منها على تحسين قابلية صيانة قاعدة الرموز وجودتها بشكل عام. يلخّص الجدول التالي المزايا الرئيسية.
المزايا
ملخّص
إمكانية إعادة الاستخدام
تتيح إمكانية التقسيم إلى وحدات فرصًا لمشاركة الرموز البرمجية وإنشاء تطبيقات متعددة من الأساس نفسه. الوحدات هي في الواقع وحدات أساسية. يجب أن تكون التطبيقات عبارة عن مجموعة من ميزاتها، ويجب تنظيم الميزات كوحدات منفصلة. قد تكون الوظيفة التي توفّرها وحدة نمطية معيّنة مفعَّلة أو غير مفعَّلة في تطبيق معيّن. على سبيل المثال، يمكن أن يكون :feature:news جزءًا من إصدار التطبيق الكامل وتطبيق Wear OS، ولكن ليس جزءًا من إصدار التطبيق التجريبي.
التحكّم الصارم في إذن الوصول
تتيح لك الوحدات التحكّم بسهولة في ما تعرضه لأجزاء أخرى من قاعدة الرموز البرمجية. يمكنك وضع علامة internal أو private على كل شيء باستثناء الواجهة العامة لمنع استخدامه خارج الوحدة.
طريقة العرض القابلة للتخصيص
تستفيد ميزة عرض الميزات في Play من الإمكانات المتقدّمة لحِزم التطبيقات، ما يتيح لك عرض ميزات معيّنة في تطبيقك بشكل مشروط أو عند الطلب.
لا يمكن الاستفادة من مزايا التقسيم إلى وحدات إلا باستخدام قاعدة رموز مقسَّمة إلى وحدات.
يمكن تحقيق المزايا التالية باستخدام تقنيات أخرى، ولكن يمكن أن تساعدك عملية التقسيم إلى وحدات في فرضها بشكل أكبر.
المزايا
ملخّص
قابلية التطور
في قاعدة الرموز البرمجية المرتبطة بإحكام، يمكن أن يؤدي تغيير واحد إلى سلسلة من التعديلات في أجزاء من الرمز تبدو غير ذات صلة. سيتبنّى المشروع الذي تم تقسيمه إلى وحدات بشكل صحيح مبدأ فصل الاهتمامات، وبالتالي سيحدّ من الربط. ويمنح ذلك المساهمين المزيد من الاستقلالية.
الملكية
بالإضافة إلى إتاحة الاستقلالية، يمكن استخدام الوحدات أيضًا لفرض المساءلة. يمكن أن يكون لكل وحدة مالك مخصّص مسؤول عن صيانة الرمز البرمجي وإصلاح الأخطاء وإضافة الاختبارات ومراجعة التغييرات.
التغليف
يعني التغليف أنّ كل جزء من الرمز البرمجي يجب أن يتضمّن أقل قدر ممكن من المعلومات حول الأجزاء الأخرى. يسهل قراءة التعليمات البرمجية المعزولة وفهمها.
إمكانية الاختبار
تشير قابلية الاختبار إلى مدى سهولة اختبار التعليمات البرمجية. قاعدة الرموز البرمجية القابلة للاختبار هي تلك التي يمكن اختبار مكوناتها بسهولة بشكل منفصل.
مدّة التصميم
يمكن لبعض وظائف Gradle، مثل الإنشاء التزايدي أو ذاكرة التخزين المؤقت للإنشاء أو الإنشاء المتوازي، الاستفادة من التصميم المعياري من أجل تحسين أداء الإنشاء.
المشاكل الشائعة
تشير دقة قاعدة الرموز البرمجية إلى مدى توفّرها على شكل وحدات. تحتوي قاعدة الرموز الأكثر تفصيلاً على وحدات أكثر وأصغر. عند تصميم قاعدة رموز برمجية مقسّمة إلى وحدات، عليك تحديد مستوى التفصيل. لإجراء ذلك،
ضَع في اعتبارك حجم قاعدة الرموز ومدى تعقيدها. سيؤدي التحديد الدقيق جدًا إلى زيادة العبء، بينما سيؤدي التحديد غير الدقيق إلى تقليل مزايا التقسيم إلى وحدات.
في ما يلي بعض المشاكل الشائعة:
التفصيل المفرط: تضيف كل وحدة مقدارًا معيّنًا من الحمل الزائد في شكل زيادة في تعقيد عملية الإنشاء ورمز النص النموذجي. تصعّب إعدادات التصميم المعقّدة الحفاظ على اتساق الإعدادات في جميع الوحدات. يؤدي استخدام الكثير من رموز النصوص النموذجية إلى إنشاء قاعدة رموز معقّدة تصعب صيانتها. إذا كانت النفقات العامة تعيق تحسينات قابلية التطور، عليك التفكير في دمج بعض الوحدات.
التفاصيل الغير كافية: على العكس من ذلك، إذا كانت وحداتك تزداد حجمًا، قد ينتهي بك الأمر إلى إنشاء بنية متكاملة أخرى وتفويت المزايا التي توفّرها تلك الوحدة. على سبيل المثال، في مشروع صغير، لا بأس بوضع طبقة البيانات داخل وحدة نمطية واحدة. ولكن مع نموّه، قد يصبح من الضروري فصل المستودعات ومصادر البيانات إلى وحدات مستقلة.
زيادة التعقيد: ليس من المنطقي دائمًا تقسيم مشروعك إلى وحدات. أحد العوامل المهمة هو حجم قاعدة الرموز البرمجية. إذا كنت لا تتوقّع أن يتجاوز مشروعك حدًا معيّنًا، لن تنطبق مزايا قابلية التطور ومدّة التصميم.
هل التقسيم إلى وحدات هو الأسلوب المناسب لي؟
إذا كنت بحاجة إلى مزايا إعادة الاستخدام أو التحكّم الدقيق في مستوى العرض أو استخدام ميزة عرض الميزات في Play، فإنّ تقسيم التطبيق إلى وحدات أمر ضروري لك. إذا لم تكن بحاجة إلى ذلك، ولكنك لا تزال تريد الاستفادة من قابلية التطور أو الملكية أو التغليف أو مدد التصميم المحسّنة، ننصحك بالتفكير في تقسيم التطبيق إلى وحدات.
النماذج
Now in Android: تطبيق Android يعمل بكامل وظائفه ويتضمّن ميزة
التقسيم إلى وحدات.
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-08-21 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-21 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["# Guide to Android app modularization\n\nA project with multiple Gradle modules is known as a multi-module project. This\nguide encompasses best practices and recommended patterns for developing\nmulti-module Android apps.\n| **Note:** This page assumes a basic familiarity with the [recommended app\n| architecture](/topic/architecture).\n\nThe growing codebase problem\n----------------------------\n\nIn an ever-growing codebase, scalability, readability, and overall code quality\noften decrease through time. This comes as a result of the codebase increasing\nin size without its maintainers taking active measures to enforce a structure\nthat is easily maintainable. Modularization is a means of structuring your\ncodebase in a way that improves maintainability and helps avoid these problems.\n\nWhat is modularization?\n-----------------------\n\nModularization is a practice of organizing a codebase into loosely coupled and\nself contained parts. Each part is a module. Each module is independent and\nserves a clear purpose. By dividing a problem into smaller and easier to solve\nsubproblems, you reduce the complexity of designing and maintaining a large\nsystem.\n**Figure 1**: Dependency graph of a sample multi-module codebase\n\nBenefits of modularization\n--------------------------\n\nThe benefits of modularization are many, though they each center upon improving\nthe maintainability and overall quality of a codebase. The following table\nsummarizes the key benefits.\n\n| Benefit | Summary |\n|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Reusability | Modularization enables opportunities for code sharing and building multiple apps from the same foundation. Modules are effectively building blocks. Apps should be a sum of their features where the features are organized as separate modules. The functionality that a certain module provides may or may not be enabled in a particular app. For example, a `:feature:news` can be a part of the full version flavor and wear app but not part of the demo version flavor. |\n| Strict visibility control | Modules enable you to easily control what you expose to other parts of your codebase. You can mark everything but your public interface as `internal` or `private` to prevent it from being used outside the module. |\n| Customizable delivery | [Play Feature Delivery](/guide/playcore/feature-delivery) uses the advanced capabilities of app bundles, allowing you to deliver certain features of your app conditionally or on demand. |\n\nThe benefits of modularization are only achievable with a modularized codebase.\nThe following benefits might be achieved with other techniques but\nmodularization can help you enforce them even more.\n\n| Benefit | Summary |\n|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Scalability | In a tightly coupled codebase a single change can trigger a cascade of alterations in seemingly unrelated parts of code. A properly modularized project will embrace the [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) principle and therefore limit the coupling. This empowers the contributors through greater autonomy. |\n| Ownership | In addition to enabling autonomy, modules can also be used to enforce accountability. A module can have a dedicated owner who is responsible for maintaining the code, fixing bugs, adding tests, and reviewing changes. |\n| Encapsulation | Encapsulation means that each part of your code should have the smallest possible amount of knowledge about other parts. Isolated code is easier to read and understand. |\n| Testability | Testability characterizes how easy it is to [test](/training/testing) your code. A testable codebase is one where components can be easily tested in isolation. |\n| Build time | Some Gradle functionalities such as incremental build, build cache or parallel build, can leverage modularity to [improve build performance](/studio/build/optimize-your-build). |\n\nCommon pitfalls\n---------------\n\nThe granularity of your codebase is the extent to which it is composed of\nmodules. A more granular codebase has more, smaller modules. When designing a\nmodularized codebase, you should decide on a level of granularity. To do so,\ntake into account the size of your codebase and its relative complexity. Going\ntoo fine-grained will make the overhead a burden, and going too coarse will\nlessen the benefits of modularization.\n\nSome common pitfalls are as follows:\n\n- **Too fine-grained** : Every module brings a certain amount of overhead in the form of increased build complexity and [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code). A complex build configuration makes it difficult to [keep configurations consistent](/topic/modularization/patterns#consistent-configuration) across modules. Too much boilerplate code results in a cumbersome codebase that is difficult to maintain. If overhead counteracts scalability improvements, you should consider consolidating some modules.\n- **Too coarse-grained**: Conversely, if your modules are growing too large you might end up with yet another monolith and miss the benefits that modularity has to offer. For example, in a small project it's ok to put the data layer inside a single module. But as it grows, it might be necessary to separate repositories and data sources into standalone modules.\n- **Too complex**: It doesn't always make sense to modularize your project. A dominating factor is the size of the codebase. If you don't expect your project to grow beyond a certain threshold, the scalability and build time gains won't apply.\n\nIs modularization the right technique for me?\n---------------------------------------------\n\nIf you need the benefits of reusability, strict visibility control or to use the\n[Play Feature Delivery](/guide/playcore/feature-delivery), then modularization is a necessity for you. If you\ndon't, but still want to benefit from improved scalability, ownership,\nencapsulation, or build times, then modularization is something worth\nconsidering.\n\nSamples\n-------\n\n- [Now in Android](https://github.com/android/nowinandroid) - fully functional Android app featuring modularization.\n- [Multi module architecture sample](https://github.com/android/architecture-samples/tree/multimodule)"]]