इस पेज पर, आर्किटेक्चर के सबसे सही तरीके और सुझाव दिए गए हैं. इन सिद्धांतों को अपनाकर, अपने ऐप्लिकेशन की क्वालिटी, मज़बूती, और स्केलेबिलिटी को बेहतर बनाएं. इनसे, ऐप्लिकेशन का रखरखाव और उसकी जांच करना भी आसान हो जाता है.
यहां दिए गए सबसे सही तरीकों को विषय के हिसाब से ग्रुप किया गया है. हर सुझाव की एक प्राथमिकता होती है. इससे पता चलता है कि सुझाव कितना असरदार है. प्राथमिकताओं की सूची यहां दी गई है:
- हमारा सुझाव है कि आप इस तरीके का इस्तेमाल करें: इस तरीके का इस्तेमाल तब तक करें, जब तक यह आपके तरीके से मेल खाता हो.
- सुझाया गया: इस तरीके से आपके ऐप्लिकेशन को बेहतर बनाने में मदद मिल सकती है.
- ज़रूरी नहीं: कुछ मामलों में, इस तरीके से आपके ऐप्लिकेशन को बेहतर बनाया जा सकता है.
लेयर्ड आर्किटेक्चर
हमारा सुझाया गया लेयर्ड आर्किटेक्चर, काम को अलग-अलग हिस्सों में बांटने के सिद्धांत पर काम करता है. यह डेटा मॉडल से यूज़र इंटरफ़ेस (यूआई) को कंट्रोल करता है. साथ ही, यह सिंगल सोर्स ऑफ़ ट्रुथ के सिद्धांत का पालन करता है और एकतरफ़ा डेटा फ़्लो के सिद्धांतों का पालन करता है. लेयर वाले आर्किटेक्चर के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| डेटा लेयर का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
डेटा लेयर, ऐप्लिकेशन के डेटा को ऐप्लिकेशन के बाकी हिस्सों के लिए उपलब्ध कराती है. साथ ही, इसमें आपके ऐप्लिकेशन के कारोबार से जुड़े लॉजिक का ज़्यादातर हिस्सा शामिल होता है.
|
| साफ़ तौर पर तय की गई यूज़र इंटरफ़ेस (यूआई) लेयर का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
यूज़र इंटरफ़ेस (यूआई) लेयर, स्क्रीन पर ऐप्लिकेशन का डेटा दिखाती है. साथ ही, यह उपयोगकर्ता के इंटरैक्शन का मुख्य पॉइंट होता है. ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) बनाने के लिए, Jetpack Compose को आधुनिक टूलकिट के तौर पर इस्तेमाल करने का सुझाव दिया जाता है.
|
| रिपॉज़िटरी का इस्तेमाल करके, डेटा लेयर से ऐप्लिकेशन डेटा को ऐक्सेस करना.
हमारा सुझाव है कि आप ऐसा करें |
पक्का करें कि यूज़र इंटरफ़ेस (यूआई) लेयर में मौजूद कॉम्पोनेंट, जैसे कि कंपोज़ेबल या ViewModels, सीधे तौर पर डेटा सोर्स से इंटरैक्ट न करें. डेटा सोर्स के उदाहरण:
|
| कोरूटीन और फ़्लो का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
लेयर के बीच कम्यूनिकेट करने के लिए, coroutines और flows का इस्तेमाल करें.
कोरूटीन के सबसे सही तरीकों के बारे में ज़्यादा जानने के लिए, Android में कोरूटीन इस्तेमाल करने के सबसे सही तरीके लेख पढ़ें. |
| डोमेन लेयर का इस्तेमाल करें.
बड़े ऐप्लिकेशन में इस्तेमाल करने का सुझाव दिया जाता है |
अगर आपको कई ViewModels में डेटा लेयर के साथ इंटरैक्ट करने वाले कारोबार के लॉजिक का फिर से इस्तेमाल करना है या आपको किसी ViewModel के कारोबार के लॉजिक को आसान बनाना है, तो इस्तेमाल के उदाहरणों के साथ डोमेन लेयर का इस्तेमाल करें |
यूज़र इंटरफ़ेस (यूआई) लेयर
यूज़र इंटरफ़ेस (यूआई) लेयर का काम, स्क्रीन पर ऐप्लिकेशन का डेटा दिखाना है. साथ ही, यह उपयोगकर्ता के इंटरैक्शन का मुख्य पॉइंट है. यूज़र इंटरफ़ेस (यूआई) लेयर के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| एक दिशा में डेटा फ़्लो (यूडीएफ़) का पालन करें.
हमारा सुझाव है कि आप ऐसा करें |
एकतरफ़ा डेटा फ़्लो (यूडीएफ़) के सिद्धांतों का पालन करें. इसमें ViewModels, ऑब्ज़र्वर पैटर्न का इस्तेमाल करके यूज़र इंटरफ़ेस (यूआई) की स्थिति को दिखाते हैं और मेथड कॉल के ज़रिए यूज़र इंटरफ़ेस (यूआई) से कार्रवाइयां पाते हैं. |
| अगर आपके ऐप्लिकेशन पर AAC ViewModels के फ़ायदे लागू होते हैं, तो उनका इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
AAC ViewModels का इस्तेमाल करके, कारोबार के लॉजिक को मैनेज करें. साथ ही, ऐप्लिकेशन का डेटा फ़ेच करके, यूज़र इंटरफ़ेस (यूआई) की स्थिति को यूज़र इंटरफ़ेस (यूआई) पर दिखाएं.
ViewModel इस्तेमाल करने के सबसे सही तरीकों के बारे में ज़्यादा जानने के लिए, आर्किटेक्चर से जुड़े सुझाव लेख पढ़ें. ViewModels के फ़ायदों के बारे में ज़्यादा जानने के लिए, The ViewModel as a business logic state holder लेख पढ़ें. |
| लाइफ़साइकल की जानकारी रखने वाले यूज़र इंटरफ़ेस की स्थिति से जुड़ा डेटा इकट्ठा करने की सुविधा का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
लाइफ़साइकल के बारे में जानकारी रखने वाले सही को-रूटीन बिल्डर, collectAsStateWithLifecycle का इस्तेमाल करके, यूज़र इंटरफ़ेस (यूआई) से यूज़र इंटरफ़ेस (यूआई) की स्थिति इकट्ठा करें.
|
| ViewModel से यूज़र इंटरफ़ेस (यूआई) को इवेंट न भेजें.
हमारा सुझाव है कि आप ऐसा करें |
इवेंट को ViewModel में तुरंत प्रोसेस करें. साथ ही, इवेंट को हैंडल करने के नतीजे के साथ स्थिति को अपडेट करें. यूज़र इंटरफ़ेस (यूआई) इवेंट के बारे में ज़्यादा जानकारी के लिए, ViewModel इवेंट मैनेज करना लेख पढ़ें. |
| एक गतिविधि वाले ऐप्लिकेशन का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
अगर आपके ऐप्लिकेशन में एक से ज़्यादा स्क्रीन हैं, तो स्क्रीन के बीच नेविगेट करने के लिए नेविगेशन 3 का इस्तेमाल करें. साथ ही, अपने ऐप्लिकेशन को डीप लिंक करें. |
| Jetpack Compose का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
फ़ोन, टैबलेट, फ़ोल्ड किए जा सकने वाले डिवाइसों, और Wear OS के लिए नए ऐप्लिकेशन बनाने के लिए, Jetpack Compose का इस्तेमाल करें. |
यहां दिए गए स्निपेट में, लाइफ़साइकल के बारे में जानकारी रखने वाले तरीके से यूज़र इंटरफ़ेस (यूआई) की स्थिति को इकट्ठा करने का तरीका बताया गया है:
@Composable
fun MyScreen(
viewModel: MyViewModel = viewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}
ViewModel
ViewModels, यूज़र इंटरफ़ेस (यूआई) की स्थिति के बारे में जानकारी देने और डेटा लेयर को ऐक्सेस करने के लिए ज़िम्मेदार होते हैं. यहां ViewModels के लिए कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| ViewModels को Android लाइफ़साइकल से अलग रखें.
हमारा सुझाव है कि आप ऐसा करें |
ViewModels में, लाइफ़साइकल से जुड़े किसी भी टाइप का रेफ़रंस न रखें. Activity, Context या Resources को डिपेंडेंसी के तौर पर पास न करें.
अगर ViewModel में किसी चीज़ के लिए Context की ज़रूरत है, तो ध्यान से देखें कि वह सही लेयर में है या नहीं. |
| कोरूटीन और फ़्लो का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
ViewModel, डेटा या डोमेन लेयर के साथ इंटरैक्ट करता है. इसके लिए, वह इनका इस्तेमाल करता है:
|
| स्क्रीन लेवल पर ViewModels का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
यूज़र इंटरफ़ेस (यूआई) के दोबारा इस्तेमाल किए जा सकने वाले हिस्सों में ViewModels का इस्तेमाल न करें. आपको ViewModels का इस्तेमाल इनमें करना चाहिए:
|
| दोबारा इस्तेमाल किए जा सकने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट में, सामान्य स्टेट होल्डर क्लास का इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
दोबारा इस्तेमाल किए जा सकने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट में जटिलता को मैनेज करने के लिए, सामान्य स्टेट होल्डर क्लास का इस्तेमाल करें. ऐसा करने पर, स्थिति को ऊपर ले जाया जा सकता है और बाहरी तौर पर कंट्रोल किया जा सकता है. |
AndroidViewModel का इस्तेमाल न करें.
सुझाया गया |
AndroidViewModel के बजाय, ViewModel क्लास का इस्तेमाल करें. ViewModel में Application क्लास का इस्तेमाल न करें. इसके बजाय, डिपेंडेंसी को यूज़र इंटरफ़ेस (यूआई) या डेटा लेयर में ले जाएं. |
| यूज़र इंटरफ़ेस (यूआई) की स्थिति को दिखाना.
सुझाया गया |
अपने ViewModels को, यूज़र इंटरफ़ेस (यूआई) के लिए डेटा उपलब्ध कराने दें. इसके लिए, 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 lifecycle के साथ काम करने के सबसे सही तरीके अपनाएं:
| सुझाव | ब्यौरा |
|---|---|
लाइफ़साइकल की जानकारी वाले इफ़ेक्ट का इस्तेमाल, कंपोज़ेबल में करें. इसके लिए, Activity लाइफ़साइकल कॉलबैक को बदलने के बजाय, इनका इस्तेमाल करें.
हमारा सुझाव है कि आप ऐसा करें |
यूज़र इंटरफ़ेस (यूआई) से जुड़े टास्क चलाने के लिए,
|
यहां दिए गए स्निपेट में, किसी लाइफ़साइकल की स्थिति के हिसाब से कार्रवाइयां करने का तरीका बताया गया है:
@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 या मैन्युअल डिपेंडेंसी इंजेक्शन का इस्तेमाल करें. अगर आपका प्रोजेक्ट काफ़ी जटिल है, तो Hilt का इस्तेमाल करें. उदाहरण के लिए, अगर इसमें इनमें से कोई भी चीज़ शामिल है:
|
टेस्ट करना
टेस्टिंग के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| जानें कि क्या टेस्ट करना है.
हमारा सुझाव है कि आप ऐसा करें |
अगर प्रोजेक्ट "नमस्ते, दुनिया के लोगों" जैसे आसान ऐप्लिकेशन के तौर पर नहीं है, तो उसकी जांच करें. कम से कम यह जानकारी शामिल करें:
|
| मॉक के बजाय फ़ेक को प्राथमिकता दें.
हमारा सुझाव है कि आप ऐसा करें |
फ़ेक ऑब्जेक्ट इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, Android में टेस्ट डबल का इस्तेमाल करना लेख पढ़ें. |
| StateFlows की जांच करें.
हमारा सुझाव है कि आप ऐसा करें |
StateFlow की टेस्टिंग करते समय, यह तरीका अपनाएं:
|
ज़्यादा जानकारी के लिए, Android में क्या टेस्ट करें और अपने Compose लेआउट की जांच करें लेख पढ़ें.
मॉडल
अपने ऐप्लिकेशन में मॉडल डेवलप करते समय, इन सबसे सही तरीकों को ध्यान में रखें:
| सुझाव | ब्यौरा |
|---|---|
| जटिल ऐप्लिकेशन में, हर लेयर के लिए एक मॉडल बनाएं.
सुझाया गया |
जटिल ऐप्लिकेशन में, जब ज़रूरत हो, तब अलग-अलग लेयर या कॉम्पोनेंट में नए मॉडल बनाएं. यहां दिए गए उदाहरण देखें:
|
नाम रखने के नियम
अपने कोडबेस का नाम रखते समय, आपको इन सबसे सही तरीकों के बारे में पता होना चाहिए:
| सुझाव | ब्यौरा |
|---|---|
| नाम रखने के तरीके.
ज़रूरी नहीं है |
तरीकों के नाम रखने के लिए, क्रिया के वाक्यांशों का इस्तेमाल करें. उदाहरण के लिए, makePayment(). |
| प्रॉपर्टी के नाम.
ज़रूरी नहीं है |
प्रॉपर्टी के नाम के लिए संज्ञा वाक्यांशों का इस्तेमाल करें. उदाहरण के लिए, inProgressTopicSelection. |
| डेटा स्ट्रीम के नाम तय करना.
ज़रूरी नहीं है |
जब कोई क्लास, फ़्लो स्ट्रीम या कोई अन्य स्ट्रीम दिखाती है, तो नाम रखने का तरीका get{model}Stream होता है. उदाहरण के लिए, getAuthorStream(): Flow<Author>.
अगर फ़ंक्शन, मॉडल की सूची दिखाता है, तो मॉडल के नाम का प्लुरल फ़ॉर्म इस्तेमाल करें: getAuthorsStream(): Flow<List<Author>>. |
| इंटरफ़ेस के नाम रखने के तरीके.
ज़रूरी नहीं है |
इंटरफ़ेस लागू करने के लिए, काम के नामों का इस्तेमाल करें. अगर कोई बेहतर नाम नहीं मिलता है, तो प्रीफ़िक्स के तौर पर Default का इस्तेमाल करें. उदाहरण के लिए, NewsRepository इंटरफ़ेस के लिए, आपके पास OfflineFirstNewsRepository या InMemoryNewsRepository हो सकता है. अगर आपको कोई अच्छा नाम नहीं मिल रहा है, तो DefaultNewsRepository का इस्तेमाल करें.
फ़र्ज़ी तौर पर लागू किए गए कोड के आगे Fake प्रीफ़िक्स लगाएं. जैसे, FakeAuthorsRepository. |
अन्य संसाधन
Android के आर्किटेक्चर के बारे में ज़्यादा जानने के लिए, यहां दिए गए अतिरिक्त संसाधन देखें: