इस पेज पर, आर्किटेक्चर के सबसे सही तरीके और सुझाव दिए गए हैं. इन्हें अपनाएं, ताकि आपके ऐप्लिकेशन की क्वालिटी, ऐप्लिकेशन की क्षमता, और ऐप्लिकेशन को बढ़ाई जा सके. इनसे आपके ऐप्लिकेशन को मैनेज करना और उसकी जांच करना भी आसान हो जाता है.
यहां दिए गए सबसे सही तरीके, विषय के हिसाब से ग्रुप किए गए हैं. हर रणनीति की अपनी प्राथमिकता होती है. इससे पता चलता है कि टीम उसे किस तरह का सुझाव देती है. प्राथमिकताओं की सूची इस तरह है:
- इसका सुझाव दिया जाता है: आपको इस तरीके को तब तक लागू करना चाहिए, जब तक कि यह आपके तरीके से मेल न खाता हो.
- सुझाया गया: ऐसा करने से आपके ऐप्लिकेशन की परफ़ॉर्मेंस बेहतर हो सकती है.
- ज़रूरी नहीं: इस तरीके से कुछ खास मामलों में आपके ऐप्लिकेशन को बेहतर बनाया जा सकता है.
लेयर्ड आर्किटेक्चर
हमारा सुझाया गया लेयर वाला आर्किटेक्चर, अलग-अलग कामों को अलग-अलग करने में मदद करता है. यह यूज़र इंटरफ़ेस (यूआई) को डेटा मॉडल से चलाता है. साथ ही, यह ट्रुथ सिद्धांत के सिंगल सोर्स का पालन करता है और एकतरफ़ा डेटा फ़्लो के सिद्धांतों का पालन करता है. लेयर वाले आर्किटेक्चर के लिए, यहां कुछ सबसे सही तरीके बताए गए हैं:
सुझाव | ब्यौरा |
---|---|
साफ़ तौर पर बताई गई डेटा लेयर का इस्तेमाल करें.
इसका सुझाव दिया जाता है |
डेटा लेयर, ऐप्लिकेशन के डेटा को बाकी ऐप्लिकेशन के लिए उपलब्ध कराती है. साथ ही, इसमें आपके ऐप्लिकेशन का ज़्यादातर कारोबारी लॉजिक शामिल होता है.
|
साफ़ तौर पर बताई गई यूज़र इंटरफ़ेस (यूआई) लेयर का इस्तेमाल करें.
खास तौर पर सुझाया गया |
यूज़र इंटरफ़ेस (यूआई) लेयर, स्क्रीन पर ऐप्लिकेशन का डेटा दिखाती है. साथ ही, यह उपयोगकर्ता इंटरैक्शन का मुख्य पॉइंट होती है.
|
डेटा लेयर को रिपॉज़िटरी का इस्तेमाल करके, ऐप्लिकेशन डेटा को एक्सपोज़ करना चाहिए.
इसका सुझाव दिया जाता है |
यूज़र इंटरफ़ेस (यूआई) लेयर में मौजूद कॉम्पोनेंट, जैसे कि कॉम्पोज़ेबल, ऐक्टिविटी या ViewModels को सीधे तौर पर डेटा सोर्स से इंटरैक्ट नहीं करना चाहिए. डेटा सोर्स के उदाहरण यहां दिए गए हैं:
|
कोरूटीन और फ़्लो का इस्तेमाल करें.
इसका सुझाव दिया जाता है |
लेयर के बीच कम्यूनिकेट करने के लिए, कोरूटीन और फ़्लो का इस्तेमाल करें.
कोरूटीन इस्तेमाल करने के कुछ और सबसे सही तरीके यहां दिए गए हैं. |
डोमेन लेयर का इस्तेमाल करें.
बड़े ऐप्लिकेशन के लिए सुझाया गया |
अगर आपको एक से ज़्यादा ViewModels में डेटा लेयर के साथ इंटरैक्ट करने वाले बिज़नेस लॉजिक का फिर से इस्तेमाल करना है या किसी खास ViewModel के बिज़नेस लॉजिक को आसान बनाना है, तो डोमेन लेयर का इस्तेमाल करें |
यूज़र इंटरफ़ेस (यूआई) लेयर
यूज़र इंटरफ़ेस (यूआई) लेयर का काम, स्क्रीन पर ऐप्लिकेशन के डेटा को दिखाना और उपयोगकर्ता इंटरैक्शन के मुख्य पॉइंट के तौर पर काम करना है. यहां यूज़र इंटरफ़ेस (यूआई) लेयर के लिए कुछ सबसे सही तरीके दिए गए हैं:
सुझाव | ब्यौरा |
---|---|
यूनीडायरेक्शनल डेटा फ़्लो (यूडीएफ़) का पालन करें.
इसका सुझाव दिया जाता है |
यूनीडायरेक्शनल डेटा फ़्लो (यूडीएफ़) के सिद्धांतों का पालन करें. इसमें, ViewModels, ऑब्ज़र्वर पैटर्न का इस्तेमाल करके यूआई की स्थिति दिखाते हैं और मेथड कॉल के ज़रिए यूआई से कार्रवाइयां पाते हैं. |
अगर AAC Viewमॉडल के फ़ायदे आपके ऐप्लिकेशन पर लागू होते हैं, तो उनका इस्तेमाल करें.
इसका सुझाव दिया जाता है |
कारोबार के लॉजिक को मैनेज करने के लिए, AAC ViewModels का इस्तेमाल करें. साथ ही, यूज़र इंटरफ़ेस (यूआई) (Compose या Android व्यू) को यूआई स्टेटस दिखाने के लिए, ऐप्लिकेशन डेटा फ़ेच करें. |
लाइफ़साइकल की जानकारी वाले यूआई स्टेट कलेक्शन का इस्तेमाल करें.
इसका सुझाव दिया जाता है |
लाइफ़साइकल के बारे में जानकारी वाले कोरूटीन बिल्डर का इस्तेमाल करके, यूज़र इंटरफ़ेस (यूआई) की स्थिति इकट्ठा करें: व्यू सिस्टम में repeatOnLifecycle और Jetpack Compose में collectAsStateWithLifecycle .
|
ViewModel से यूज़र इंटरफ़ेस (यूआई) पर इवेंट न भेजें.
खास तौर पर सुझाया गया |
इवेंट को ViewModel में तुरंत प्रोसेस करें और इवेंट को हैंडल करने के बाद स्टेटस अपडेट करें. यूज़र इंटरफ़ेस (यूआई) इवेंट के बारे में यहां ज़्यादा जानें. |
किसी एक गतिविधि वाले ऐप्लिकेशन का इस्तेमाल करें.
सुझाया गया |
अगर आपके ऐप्लिकेशन में एक से ज़्यादा स्क्रीन हैं, तो स्क्रीन के बीच नेविगेट करने और अपने ऐप्लिकेशन को डीप लिंक करने के लिए, नेविगेशन फ़्रैगमेंट या नेविगेशन कंपोज का इस्तेमाल करें. |
Jetpack Compose का इस्तेमाल करें.
सुझाव |
फ़ोन, टैबलेट, फ़ोल्ड किए जा सकने वाले फ़ोन, और Wear OS के लिए नए ऐप्लिकेशन बनाने के लिए, Jetpack Compose का इस्तेमाल करें. |
नीचे दिए गए स्निपेट में, लाइफ़साइकल के हिसाब से यूज़र इंटरफ़ेस (यूआई) की स्थिति इकट्ठा करने का तरीका बताया गया है:
व्यू
class MyFragment : Fragment() {
private val viewModel: MyViewModel by viewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Process item
}
}
}
}
}
Compose
@Composable
fun MyScreen(
viewModel: MyViewModel = viewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}
ViewModel
ViewModels, यूज़र इंटरफ़ेस (यूआई) की स्थिति और डेटा लेयर का ऐक्सेस देने के लिए ज़िम्मेदार होते हैं. ViewModels के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
सुझाव | ब्यौरा |
---|---|
ViewModels, Android लाइफ़साइकल के बारे में नहीं जाने चाहिए.
इसका सुझाव दिया जाता है |
ViewModels में, लाइफ़साइकल से जुड़े किसी भी टाइप का रेफ़रंस नहीं होना चाहिए. Activity, Fragment, 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
)
// ...
}
लाइफ़साइकल
Android लाइफ़साइकल के साथ काम करने के कुछ सबसे सही तरीके यहां दिए गए हैं:
सुझाव | ब्यौरा |
---|---|
ऐक्टिविटी या फ़्रैगमेंट में लाइफ़साइकल के तरीकों को बदलें नहीं.
इसका सुझाव दिया जाता है |
ऐक्टिविटी या फ़्रैगमेंट में, लाइफ़साइकल के onResume जैसे मेथड को बदलें. इसके बजाय, LifecycleObserver का इस्तेमाल करें. अगर ऐप्लिकेशन को लाइफ़साइकल के किसी खास Lifecycle.State पर कोई काम करना है, तो repeatOnLifecycle एपीआई का इस्तेमाल करें. |
नीचे दिए गए स्निपेट में, लाइफ़साइकल की किसी खास स्थिति के हिसाब से कार्रवाइयां करने का तरीका बताया गया है:
व्यू
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
// ...
}
override fun onPause(owner: LifecycleOwner) {
// ...
}
}
}
}
Compose
@Composable
fun MyApp() {
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner, ...) {
val lifecycleObserver = object : DefaultLifecycleObserver {
override fun onStop(owner: LifecycleOwner) {
// ...
}
}
lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
}
}
}
डिपेंडेंसी हैंडल करता है
कॉम्पोनेंट के बीच डिपेंडेंसी मैनेज करते समय, आपको कई सबसे सही तरीकों का पालन करना चाहिए:
सुझाव | ब्यौरा |
---|---|
डिपेंडेंसी इंजेक्शन का इस्तेमाल करें.
इसका सुझाव दिया जाता है |
जब भी हो सके, डिपेंडेंसी इंजेक्शन के सबसे सही तरीकों का इस्तेमाल करें. खास तौर पर, कंस्ट्रक्टर इंजेक्शन का इस्तेमाल करें. |
ज़रूरत पड़ने पर, किसी कॉम्पोनेंट के लिए स्कोप तय करें.
इसका सुझाव दिया जाता है |
जब टाइप में ऐसा डेटा हो जिसे शेयर करना ज़रूरी हो या टाइप को शुरू करने में ज़्यादा समय लगता हो और ऐप्लिकेशन में इसका ज़्यादा इस्तेमाल किया जाता हो, तो डिपेंडेंसी कंटेनर के दायरे में रखें. |
Hilt का इस्तेमाल करें.
सुझाया गया |
आसान ऐप्लिकेशन में, Hilt या मैन्युअल डिपेंडेंसी इंजेक्शन का इस्तेमाल करें. अगर आपका प्रोजेक्ट काफ़ी जटिल है, तो Hilt का इस्तेमाल करें. उदाहरण के लिए, अगर आपके पास:
|
टेस्ट करना
जांच के लिए, यहां कुछ सबसे सही तरीके दिए गए हैं:
सुझाव | ब्यौरा |
---|---|
जानें कि क्या टेस्ट करना है.
इसका सुझाव दिया जाता है |
अगर प्रोजेक्ट, 'हैलो वर्ल्ड' ऐप्लिकेशन जितना आसान नहीं है, तो आपको कम से कम इनके साथ इसकी जांच करनी चाहिए:
|
नकल करने के बजाय, नकली चीज़ों को प्राथमिकता देनी है.
खास तौर पर सुझाया गया |
ज़्यादा जानकारी के लिए, Android दस्तावेज़ में टेस्ट डबल का इस्तेमाल करना लेख पढ़ें. |
टेस्ट स्टेट फ़्लो.
इसका सुझाव दिया जाता है |
StateFlow की जांच करते समय:
|
ज़्यादा जानकारी के लिए, Android DAC गाइड में क्या जांचना है लेख पढ़ें.
मॉडल
अपने ऐप्लिकेशन में मॉडल डेवलप करते समय, आपको इन सबसे सही तरीकों को देखना चाहिए:
सुझाव | ब्यौरा |
---|---|
जटिल ऐप्लिकेशन में हर लेयर के लिए मॉडल बनाएं.
सुझाव |
जटिल ऐप्लिकेशन में, अलग-अलग लेयर या कॉम्पोनेंट में नए मॉडल बनाएं. नीचे दिए गए उदाहरण देखें:
|
नाम रखने के तरीके
अपने कोड बेस को नाम देते समय, आपको इन सबसे सही तरीकों के बारे में जानकारी होनी चाहिए:
सुझाव | ब्यौरा |
---|---|
नाम रखने के तरीके.
ज़रूरी नहीं |
तरीके, क्रिया के वाक्यांश होने चाहिए. उदाहरण के लिए, makePayment() . |
नाम रखने से जुड़ी प्रॉपर्टी.
ज़रूरी नहीं है |
प्रॉपर्टी, संज्ञा वाक्यांश होनी चाहिए. उदाहरण के लिए, inProgressTopicSelection . |
डेटा की स्ट्रीम को नाम देना.
ज़रूरी नहीं |
जब कोई क्लास किसी फ़्लो स्ट्रीम, LiveData या किसी अन्य स्ट्रीम को एक्सपोज़ करती है, तो नाम रखने का तरीका get{model}Stream() होता है. उदाहरण के लिए, getAuthorStream(): Flow<Author>
अगर फ़ंक्शन मॉडल की सूची दिखाता है, तो मॉडल का नाम बहुवचन में होना चाहिए: getAuthorsStream(): Flow<List<Author>> |
इंटरफ़ेस के नाम तय करना.
ज़रूरी नहीं है |
इंटरफ़ेस लागू करने के लिए, काम के नाम होने चाहिए. अगर कोई बेहतर नाम नहीं मिलता है, तो प्रीफ़िक्स के तौर पर Default का इस्तेमाल करें. उदाहरण के लिए, NewsRepository इंटरफ़ेस के लिए, आपके पास OfflineFirstNewsRepository या InMemoryNewsRepository हो सकता है. अगर आपको कोई अच्छा नाम नहीं मिलता है, तो DefaultNewsRepository का इस्तेमाल करें.
नकली तरीके को लागू करने के लिए, Fake का इस्तेमाल करना चाहिए, जैसे कि FakeAuthorsRepository में. |