این صفحه چندین شیوه و توصیه برتر معماری را ارائه میدهد. آنها را برای بهبود کیفیت، استحکام و مقیاسپذیری برنامه خود به کار بگیرید. آنها همچنین نگهداری و آزمایش برنامه شما را آسانتر میکنند.
بهترین شیوههای زیر بر اساس موضوع گروهبندی شدهاند. هر کدام اولویتی دارند که نشان دهنده میزان قوت توصیه است. فهرست اولویتها به شرح زیر است:
- اکیداً توصیه میشود: این روش را اجرا کنید، مگر اینکه اساساً با رویکرد شما مغایرت داشته باشد.
- توصیه میشود: این روش احتمالاً برنامه شما را بهبود میبخشد.
- اختیاری: این روش میتواند در شرایط خاص، برنامه شما را بهبود بخشد.
معماری لایهای
معماری لایهای پیشنهادی ما، تفکیک دغدغهها را ترجیح میدهد. این معماری، رابط کاربری را از مدلهای دادهای هدایت میکند، از اصل منبع واحد حقیقت پیروی میکند و از اصول جریان داده یکطرفه پیروی میکند. در اینجا چند نمونه از بهترین شیوهها برای معماری لایهای آورده شده است:
| توصیه | توضیحات |
|---|---|
| از یک لایه داده کاملاً تعریفشده استفاده کنید. اکیداً توصیه میشود | لایه داده ، دادههای برنامه را در معرض بقیه برنامه قرار میدهد و بخش عمدهای از منطق تجاری برنامه شما را در بر میگیرد.
|
| از یک لایه رابط کاربری (UI) کاملاً تعریفشده استفاده کنید. اکیداً توصیه میشود | لایه رابط کاربری، دادههای برنامه را روی صفحه نمایش میدهد و به عنوان نقطه اصلی تعامل کاربر عمل میکند. Jetpack Compose ابزار مدرن پیشنهادی برای ساخت رابط کاربری برنامه شماست.
|
| دادههای برنامه را از لایه داده با استفاده از یک مخزن (repository) در معرض نمایش قرار دهید. اکیداً توصیه میشود | مطمئن شوید که کامپوننتهای موجود در لایه رابط کاربری مانند composableها یا ViewModelها مستقیماً با منبع داده تعامل ندارند. نمونههایی از منابع داده عبارتند از:
|
| از کوروتینها و جریانها استفاده کنید. اکیداً توصیه میشود | از کوروتینها و جریانها برای ارتباط بین لایهها استفاده کنید. برای اطلاعات بیشتر در مورد بهترین شیوههای کوروتین، به بهترین شیوههای کوروتین در اندروید مراجعه کنید. |
| از یک لایه دامنه استفاده کنید. در برنامههای بزرگ توصیه میشود | اگر نیاز به استفاده مجدد از منطق کسبوکاری دارید که با لایه داده در چندین ViewModel تعامل دارد، یا میخواهید پیچیدگی منطق کسبوکار یک ViewModel خاص را ساده کنید، از یک لایه دامنه با موارد استفاده استفاده کنید. |
لایه رابط کاربری
نقش لایه رابط کاربری نمایش دادههای برنامه روی صفحه نمایش و ایفای نقش به عنوان نقطه اصلی تعامل کاربر است. در اینجا چند نمونه از بهترین شیوهها برای لایه رابط کاربری آورده شده است:
| توصیه | توضیحات |
|---|---|
| جریان داده یکطرفه (UDF) را دنبال کنید. اکیداً توصیه میشود | از اصول جریان داده یکطرفه (UDF) پیروی کنید، که در آن ViewModelها با استفاده از الگوی ناظر، وضعیت رابط کاربری را نمایش میدهند و از طریق فراخوانی متدها، اقدامات را از رابط کاربری دریافت میکنند. |
| اگر مزایای AAC ViewModels در برنامه شما صدق میکند، از آنها استفاده کنید. اکیداً توصیه میشود | از AAC ViewModels برای مدیریت منطق کسب و کار و واکشی دادههای برنامه برای نمایش وضعیت رابط کاربری به رابط کاربری استفاده کنید. برای اطلاعات بیشتر در مورد بهترین شیوههای ViewModel، به توصیههای معماری مراجعه کنید. برای اطلاعات بیشتر در مورد مزایای ViewModelها، به ViewModel به عنوان یک نگهدارنده وضعیت منطق کسب و کار مراجعه کنید. |
| از مجموعه وضعیت رابط کاربری آگاه از چرخه حیات استفاده کنید. اکیداً توصیه میشود | با استفاده از سازندهی کوروتینِ آگاه از چرخهی حیاتِ مناسب، collectAsStateWithLifecycle ، وضعیت رابط کاربری را از رابط کاربری جمعآوری کنید. درباره |
| رویدادها را از ViewModel به UI ارسال نکنید. اکیداً توصیه میشود | رویداد را فوراً در ViewModel پردازش کنید و باعث بهروزرسانی وضعیت با نتیجهی مدیریت رویداد شوید. برای اطلاعات بیشتر در مورد رویدادهای رابط کاربری، به Handle ViewModel events مراجعه کنید. |
| از یک برنامه تک فعالیتی استفاده کنید. اکیداً توصیه میشود | اگر برنامه شما بیش از یک صفحه دارد، از Navigation 3 برای پیمایش بین صفحات و پیوند عمیق به برنامه خود استفاده کنید. |
| از جتپک کامپوز استفاده کنید. اکیداً توصیه میشود | از Jetpack Compose برای ساخت برنامههای جدید برای تلفنها، تبلتها، دستگاههای تاشو و Wear OS استفاده کنید. |
قطعه کد زیر نحوه جمعآوری وضعیت رابط کاربری را به شیوهای آگاه از چرخه حیات (lifecycle-aware) شرح میدهد:
@Composable
fun MyScreen(
viewModel: MyViewModel = viewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}
ویو مدل
ViewModelها مسئول ارائه وضعیت رابط کاربری و دسترسی به لایه داده هستند. در اینجا چند نمونه از بهترین شیوهها برای ViewModelها آورده شده است:
| توصیه | توضیحات |
|---|---|
| ViewModelها را مستقل از چرخه حیات اندروید نگه دارید. اکیداً توصیه میشود | در ViewModelها، به هیچ نوع مرتبط با چرخه حیات ارجاع ندهید. Activity ، Context یا Resources به عنوان وابستگی ارسال نکنید. اگر چیزی در ViewModel به Context نیاز دارد، با دقت ارزیابی کنید که آیا در لایه مناسب قرار دارد یا خیر. |
| از کوروتینها و جریانها استفاده کنید. اکیداً توصیه میشود | ViewModel با استفاده از موارد زیر با لایههای داده یا دامنه تعامل میکند:
|
| از ViewModelها در سطح صفحه نمایش استفاده کنید. اکیداً توصیه میشود | از ViewModelها در بخشهای قابل استفاده مجدد رابط کاربری استفاده نکنید. شما باید از ViewModelها در موارد زیر استفاده کنید:
|
| از کلاسهای نگهدارندهی حالت ساده در کامپوننتهای رابط کاربری قابل استفاده مجدد استفاده کنید. اکیداً توصیه میشود | از کلاسهای نگهدارندهی حالت ساده برای مدیریت پیچیدگی در کامپوننتهای رابط کاربری قابل استفاده مجدد استفاده کنید. وقتی این کار را انجام میدهید، حالت میتواند به صورت خارجی منتقل و کنترل شود. |
AndroidViewModel استفاده نکنید. توصیه شده | از کلاس ViewModel استفاده کنید، نه AndroidViewModel . از کلاس Application در ViewModel استفاده نکنید. در عوض، وابستگی را به رابط کاربری یا لایه داده منتقل کنید. |
| نمایش وضعیت رابط کاربری (UI). توصیه شده | کاری کنید که ViewModel های شما از طریق یک ویژگی واحد به نام uiState ، دادهها را در اختیار رابط کاربری قرار دهند. اگر رابط کاربری چندین قطعه داده نامرتبط را نشان دهد، ماشین مجازی میتواند چندین ویژگی وضعیت رابط کاربری را در معرض نمایش قرار دهد .
|
قطعه کد زیر نحوه نمایش وضعیت رابط کاربری از یک ViewModel را شرح میدهد:
@HiltViewModel
class BookmarksViewModel @Inject constructor(
newsRepository: NewsRepository
) : ViewModel() {
val feedState: StateFlow<NewsFeedUiState> =
newsRepository
.getNewsResourcesStream()
.mapToFeedState(savedNewsResourcesState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading
)
// ...
}
چرخه حیات
برای کار با چرخه حیات اکتیویتی ، بهترین شیوهها را دنبال کنید:
| توصیه | توضیحات |
|---|---|
به جای لغو فراخوانیهای چرخه حیات Activity ، از افکتهای آگاه از چرخه حیات در composableها استفاده کنید. اکیداً توصیه میشود | برای اجرای وظایف مرتبط با رابط کاربری، متدهای چرخه حیات
|
قطعه کد زیر نحوه انجام عملیات با توجه به یک وضعیت چرخه حیات خاص را شرح میدهد:
@Composable
fun LocationChangedEffect(
locationManager: LocationManager,
onLocationChanged: (Location) -> Unit
) {
val currentOnLocationChanged by rememberUpdatedState(onLocationChanged)
LifecycleStartEffect(locationManager) {
val listener = LocationListener { newLocation ->
currentOnLocationChanged(newLocation)
}
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000L,
1f,
listener,
)
} catch (e: SecurityException) {
// TODO: Handle missing permissions
}
onStopOrDispose {
locationManager.removeUpdates(listener)
}
}
}
مدیریت وابستگیها
هنگام مدیریت وابستگیها بین اجزا، از بهترین شیوهها پیروی کنید:
| توصیه | توضیحات |
|---|---|
| از تزریق وابستگی استفاده کنید. اکیداً توصیه میشود | از بهترین شیوههای تزریق وابستگی ، عمدتاً در صورت امکان از تزریق سازنده، استفاده کنید. |
| در صورت لزوم، به یک جزء دسترسی داشته باشید. اکیداً توصیه میشود | محدوده به یک ظرف وابستگی زمانی که نوع شامل دادههای قابل تغییر است که باید به اشتراک گذاشته شوند یا نوع برای مقداردهی اولیه پرهزینه است و به طور گسترده در برنامه استفاده میشود. |
| از هیلت استفاده کنید. توصیه شده | در برنامههای ساده از Hilt یا تزریق وابستگی دستی استفاده کنید. اگر پروژه شما به اندازه کافی پیچیده است - مثلاً اگر شامل هر یک از موارد زیر است - از Hilt استفاده کنید:
|
آزمایش
در ادامه به برخی از بهترین شیوههای آزمایش اشاره شده است:
| توصیه | توضیحات |
|---|---|
| بدانید چه چیزی را آزمایش کنید . اکیداً توصیه میشود | مگر اینکه پروژه به سادگی یک برنامه "hello world" باشد، آن را آزمایش کنید. حداقل موارد زیر را در آن بگنجانید:
|
| چیزهای قلابی را به چیزهای ساختگی ترجیح میدهند. اکیداً توصیه میشود | برای اطلاعات بیشتر در مورد استفاده از مقادیر جعلی، به بخش «استفاده از مقادیر آزمایشی مضاعف در اندروید» مراجعه کنید. |
| جریانهای حالت (StateFlows) را آزمایش کنید. اکیداً توصیه میشود | هنگام آزمایش StateFlow ، موارد زیر را انجام دهید:
|
برای اطلاعات بیشتر، به «چه چیزهایی را در اندروید آزمایش کنیم» و «طرحبندی Compose خود را آزمایش کنید» مراجعه کنید.
مدلها
هنگام توسعه مدلها در برنامههای خود، این بهترین شیوهها را رعایت کنید:
| توصیه | توضیحات |
|---|---|
| در برنامههای پیچیده، برای هر لایه یک مدل ایجاد کنید. توصیه شده | در برنامههای پیچیده، در صورت لزوم، مدلهای جدید را در لایهها یا کامپوننتهای مختلف ایجاد کنید. مثالهای زیر را در نظر بگیرید:
|
قراردادهای نامگذاری
هنگام نامگذاری پایگاه کد خود، باید از بهترین شیوههای زیر آگاه باشید:
| توصیه | توضیحات |
|---|---|
| روشهای نامگذاری. اختیاری | از عبارات فعلی برای نامگذاری متدها استفاده کنید - برای مثال، makePayment() . |
| ویژگیهای نامگذاری. اختیاری | از عبارات اسمی برای نامگذاری ویژگیها استفاده کنید - برای مثال، inProgressTopicSelection . |
| نامگذاری جریانهای داده اختیاری | وقتی یک کلاس، یک جریان Flow یا هر جریان دیگری را در معرض نمایش قرار میدهد، قرارداد نامگذاری get{model}Stream است. برای مثال، getAuthorStream(): Flow<Author> . اگر تابع لیستی از مدلها را برمیگرداند، از نام مدل جمع استفاده کنید: getAuthorsStream(): Flow<List<Author>> . |
| نامگذاری پیادهسازیهای رابطها اختیاری | از نامهای معنادار برای پیادهسازی رابطها استفاده کنید. اگر نام بهتری پیدا نشد، Default به عنوان پیشوند استفاده کنید. برای مثال، برای یک رابط NewsRepository ، ممکن است OfflineFirstNewsRepository یا InMemoryNewsRepository داشته باشید. اگر نام خوبی پیدا نکردید، DefaultNewsRepository استفاده کنید. پیادهسازیهای جعلی را با Fake پیشوند کنید، مانند FakeAuthorsRepository . |
منابع اضافی
برای اطلاعات بیشتر در مورد معماری اندروید، به منابع اضافی زیر مراجعه کنید: