इस पेज पर, आर्किटेक्चर के लिए सबसे सही तरीके और सुझाव दिए गए हैं. इन्हें अपनाकर, अपने ऐप्लिकेशन की क्वालिटी, मज़बूती, और स्केलेबिलिटी को बेहतर बनाएं. इनसे, अपने ऐप्लिकेशन को बनाए रखना और उसकी जांच करना भी आसान हो जाता है.
यहां दिए गए सबसे सही तरीकों को विषय के हिसाब से ग्रुप किया गया है. हर तरीके की एक प्राथमिकता होती है, जिससे पता चलता है कि वह सुझाव कितना ज़रूरी है. प्राथमिकताओं की सूची यहां दी गई है:
- ज़रूर अपनाएं: इस तरीके को तब तक अपनाएं, जब तक यह आपके तरीके से पूरी तरह मेल न खाता हो.
- अपनाएं: इस तरीके से, आपके ऐप्लिकेशन को बेहतर बनाने में मदद मिल सकती है.
- ज़रूरी नहीं: इस तरीके से, कुछ मामलों में आपके ऐप्लिकेशन को बेहतर बनाने में मदद मिल सकती है.
लेयर्ड आर्किटेक्चर
हमारा सुझाया गया लेयर्ड आर्किटेक्चर, अलग-अलग काम करने के सिद्धांत पर आधारित है. यह यूज़र इंटरफ़ेस (यूआई) को डेटा मॉडल से चलाता है, सिंगल सोर्स ऑफ़ ट्रुथ के सिद्धांत का पालन करता है, और एक दिशा में डेटा फ़्लो के सिद्धांतों का पालन करता है. लेयर्ड आर्किटेक्चर के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| साफ़ तौर पर तय की गई डेटा लेयर का इस्तेमाल करें.
ज़रूर अपनाएं |
डेटा लेयर, ऐप्लिकेशन के डेटा को बाकी ऐप्लिकेशन के लिए उपलब्ध कराती है. साथ ही, इसमें आपके ऐप्लिकेशन की ज़्यादातर बिज़नेस लॉजिक शामिल होती है.
|
| साफ़ तौर पर तय की गई यूज़र इंटरफ़ेस (यूआई) लेयर का इस्तेमाल करें.
ज़रूर अपनाएं |
यूज़र इंटरफ़ेस (यूआई) लेयर, स्क्रीन पर ऐप्लिकेशन का डेटा दिखाती है. साथ ही, यह उपयोगकर्ता के इंटरैक्शन के लिए मुख्य पॉइंट के तौर पर काम करती है. Jetpack Compose, आपके ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) बनाने के लिए, सुझाया गया मॉर्डन टूलकिट है.
|
| रिपॉज़िटरी का इस्तेमाल करके, डेटा लेयर से ऐप्लिकेशन का डेटा उपलब्ध कराएं.
ज़रूर अपनाएं |
पक्का करें कि यूज़र इंटरफ़ेस (यूआई) लेयर में मौजूद कॉम्पोनेंट, जैसे कि कंपोज़ेबल या ViewModels, सीधे डेटा सोर्स से इंटरैक्ट न करें. डेटा सोर्स के उदाहरण:
|
| कोरूटीन और फ़्लो का इस्तेमाल करें.
ज़रूर अपनाएं |
लेयर के बीच कम्यूनिकेट करने के लिए, कोरूटीन और फ़्लो का इस्तेमाल करें.
कोरूटीन के सबसे सही तरीकों के बारे में ज़्यादा जानने के लिए, Android में कोरूटीन के लिए सबसे सही तरीके देखें. |
| डोमेन लेयर का इस्तेमाल करें.
बड़े ऐप्लिकेशन में अपनाएं |
अगर आपको एक से ज़्यादा ViewModels में, डेटा लेयर के साथ इंटरैक्ट करने वाले बिज़नेस लॉजिक का फिर से इस्तेमाल करना है या किसी खास ViewModel के बिज़नेस लॉजिक की जटिलता को कम करना है, तो यूज़ केस के साथ डोमेन लेयर का इस्तेमाल करें |
यूज़र इंटरफ़ेस (यूआई) लेयर
यूज़र इंटरफ़ेस (यूआई) लेयर का काम, स्क्रीन पर ऐप्लिकेशन का डेटा दिखाना और उपयोगकर्ता के इंटरैक्शन के लिए मुख्य पॉइंट के तौर पर काम करना है. यूज़र इंटरफ़ेस (यूआई) लेयर के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| एक दिशा में डेटा फ़्लो (यूडीएफ़) के सिद्धांत का पालन करें.
ज़रूर अपनाएं |
एक दिशा में डेटा फ़्लो (यूडीएफ़) के सिद्धांतों का पालन करें. इसके तहत, ViewModels, ऑब्ज़र्वर पैटर्न का इस्तेमाल करके यूज़र इंटरफ़ेस (यूआई) की स्थिति को दिखाते हैं. साथ ही, मेथड कॉल के ज़रिए यूज़र इंटरफ़ेस (यूआई) से कार्रवाइयां पाते हैं. |
| अगर AAC ViewModels के फ़ायदे आपके ऐप्लिकेशन पर लागू होते हैं, तो उनका इस्तेमाल करें.
ज़रूर अपनाएं |
बिज़नेस लॉजिक को हैंडल करने और यूज़र इंटरफ़ेस (यूआई) की स्थिति को यूज़र इंटरफ़ेस (यूआई) के लिए उपलब्ध कराने के लिए, AAC ViewModels का इस्तेमाल करें. साथ ही, ऐप्लिकेशन का डेटा फ़ेच करें.
ViewModel के सबसे सही तरीकों के बारे में ज़्यादा जानने के लिए, आर्किटेक्चर के सुझाव देखें. ViewModels के फ़ायदों के बारे में ज़्यादा जानने के लिए, ViewModel को बिज़नेस लॉजिक स्टेट होल्डर के तौर पर इस्तेमाल करना देखें. |
| लाइफ़साइकल के बारे में जानकारी रखने वाले यूज़र इंटरफ़ेस (यूआई) की स्थिति के कलेक्शन का इस्तेमाल करें.
ज़रूर अपनाएं |
लाइफ़साइकल के बारे में जानकारी रखने वाले सही कोरूटीन बिल्डर, collectAsStateWithLifecycle का इस्तेमाल करके, यूज़र इंटरफ़ेस (यूआई) से यूज़र इंटरफ़ेस (यूआई) की स्थिति इकट्ठा करें.
|
| ViewModel से यूज़र इंटरफ़ेस (यूआई) पर इवेंट न भेजें.
ज़रूर अपनाएं |
ViewModel में तुरंत इवेंट प्रोसेस करें और इवेंट को हैंडल करने के नतीजे के साथ, स्थिति को अपडेट करें. यूज़र इंटरफ़ेस (यूआई) के इवेंट के बारे में ज़्यादा जानने के लिए, ViewModel के इवेंट हैंडल करना देखें. |
| सिंगल-ऐक्टिविटी ऐप्लिकेशन का इस्तेमाल करें.
ज़रूर अपनाएं |
अगर आपके ऐप्लिकेशन में एक से ज़्यादा स्क्रीन हैं, तो स्क्रीन के बीच नेविगेट करने के लिए Navigation 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 का इस्तेमाल करना चाहिए:
ज़्यादा जटिल कंपोज़ेबल या स्थिति के आधार पर डाइनैमिक व्यवहार वाले कंपोज़ेबल के लिए, ViewModel को सीधे कंपोज़ेबल की कॉल साइट पर स्कोप करने के लिए, |
| फिर से इस्तेमाल किए जा सकने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट में, सामान्य स्टेट होल्डर क्लास का इस्तेमाल करें.
ज़रूर अपनाएं |
फिर से इस्तेमाल किए जा सकने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट में जटिलता को हैंडल करने के लिए, सामान्य स्टेट होल्डर क्लास का इस्तेमाल करें. ऐसा करने पर, स्थिति को होस्ट किया जा सकता है और उसे बाहरी तौर पर कंट्रोल किया जा सकता है. |
AndroidViewModel का इस्तेमाल न करें.
अपनाएं |
ViewModel क्लास का इस्तेमाल करें, न कि AndroidViewModel का. 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 लाइफ़साइकल कॉलबैक को ओवरराइड करने के बजाय, कंपोज़ेबल में लाइफ़साइकल के बारे में जानकारी रखने वाले इफ़ेक्ट का इस्तेमाल करें.
ज़रूर अपनाएं |
यूज़र इंटरफ़ेस (यूआई) से जुड़े टास्क चलाने के लिए,
|
यहां दिए गए स्निपेट में, लाइफ़साइकल की किसी खास स्थिति के हिसाब से कार्रवाइयां करने का तरीका बताया गया है:
@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 का इस्तेमाल करें. उदाहरण के लिए, अगर इसमें इनमें से कोई भी चीज़ शामिल है:
|
जांच करना
जांच करने के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
| सुझाव | ब्यौरा |
|---|---|
| जानें कि क्या टेस्ट करना है.
ज़रूर अपनाएं |
अगर प्रोजेक्ट, "hello world" ऐप्लिकेशन जितना आसान नहीं है, तो उसकी जांच करें. कम से कम, इनमें शामिल करें:
|
| मॉक के बजाय फ़ेक का इस्तेमाल करें.
ज़रूर अपनाएं |
फ़ेक का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, 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 आर्किटेक्चर के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें: