国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android開發(fā)中的前五個(gè)代碼異味:Jetpack Compose UI和MVVM

這篇具有很好參考價(jià)值的文章主要介紹了Android開發(fā)中的前五個(gè)代碼異味:Jetpack Compose UI和MVVM。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Android開發(fā)中的前五個(gè)代碼異味:Jetpack Compose UI和MVVM

Android開發(fā)中的前五個(gè)代碼異味:Jetpack Compose UI和MVVM

代碼異味是指軟件代碼中潛在問題的指標(biāo),可能并不一定是錯(cuò)誤,但可能會(huì)導(dǎo)致問題,如增加維護(hù)復(fù)雜性、降低性能或降低可讀性。我們將探討Android開發(fā)中的前五個(gè)代碼異味,其中包括使用Jetpack Compose UI和Model-View-ViewModel(MVVM)架構(gòu)的示例。

1. 上帝對(duì)象或上帝類:

上帝對(duì)象或上帝類是指試圖做太多事情的單個(gè)類,違反了單一職責(zé)原則。在Android開發(fā)中,這可能會(huì)使代碼更難理解、維護(hù)和修改。

示例:

我們將以一個(gè)充當(dāng)“上帝對(duì)象”的ViewModel為例,然后使用存儲(chǔ)庫模式進(jìn)行重構(gòu)。

上帝對(duì)象ViewModel示例:

class GodObjectViewModel : ViewModel() {
    private val apiService = ApiService()
    private val database = AppDatabase.getInstance()

    // LiveData to expose data to the UI
    private val _data = MutableLiveData<List<DataItem>>()
    val data: LiveData<List<DataItem>> = _data

    init {
        loadData()
    }

    private fun loadData() {
        viewModelScope.launch {
            // Fetch data from API
            val apiData = apiService.getData()

            // Save data to database
            database.dataDao().insertAll(apiData)

            // Load data from database
            val dbData = database.dataDao().getAll()

            // Transform data
            val transformedData = transformData(dbData)

            // Update LiveData
            _data.value = transformedData
        }
    }

    private fun transformData(input: List<DataItem>): List<DataItem> {
        // Perform some transformations on the data
        // ...
        return transformedData
    }
}

使用倉庫模式重構(gòu)后的 ViewModel:

class RefactoredViewModel(private val dataRepository: DataRepository) : ViewModel() {
    // LiveData to expose data to the UI
    private val _data = MutableLiveData<List<DataItem>>()
    val data: LiveData<List<DataItem>> = _data

    init {
        loadData()
    }

    private fun loadData() {
        viewModelScope.launch {
            // Fetch data using the repository
            val transformedData = dataRepository.fetchData()

            // Update LiveData
            _data.value = transformedData
        }
    }
}

為了改進(jìn)代碼,我們使用倉庫模式對(duì) ViewModel 進(jìn)行了重構(gòu)。我們創(chuàng)建了一個(gè)獨(dú)立的 DataRepository 類,它負(fù)責(zé)處理 API 調(diào)用、數(shù)據(jù)庫操作和數(shù)據(jù)轉(zhuǎn)換的職責(zé)。然后,重構(gòu)后的 ViewModel 被簡(jiǎn)化為僅專注于通過委托數(shù)據(jù)獲取任務(wù)到 DataRepository 來向 UI 公開數(shù)據(jù)。

2. 深層繼承層次結(jié)構(gòu):

過度使用繼承可能導(dǎo)致代碼復(fù)雜且難以維護(hù)。在適當(dāng)?shù)那闆r下,應(yīng)優(yōu)先考慮組合而非繼承。

示例:

使用 Kotlin 和 Jetpack Compose,展示了一個(gè)深層的繼承層次結(jié)構(gòu),然后使用組合對(duì)其進(jìn)行了重構(gòu)。

abstract class BaseComposable {
    abstract fun DrawScope.draw()
}

class FirstLevelComposable : BaseComposable() {
    override fun DrawScope.draw() {
        // Implement some functionality
    }
}

class SecondLevelComposable : FirstLevelComposable() {
    override fun DrawScope.draw() {
        super.draw()
        // Add more functionality
    }
}

class ThirdLevelComposable : SecondLevelComposable() {
    override fun DrawScope.draw() {
        super.draw()
        // Add even more functionality
    }
}

@Composable
fun DeepInheritanceHierarchyExample() {
    val thirdLevelComposable = ThirdLevelComposable()

    Canvas(modifier = Modifier.fillMaxSize()) {
        thirdLevelComposable.draw()
    }
}

使用組合進(jìn)行重構(gòu):

@Composable
fun BaseComposable() {
    // Implement some functionality
}

@Composable
fun FirstLevelComposable() {
    BaseComposable()
    // Add more functionality
}

@Composable
fun SecondLevelComposable() {
    FirstLevelComposable()
    // Add even more functionality
}

@Composable
fun CompositionExample() {
    Canvas(modifier = Modifier.fillMaxSize()) {
        SecondLevelComposable()
    }
}

在重構(gòu)的示例中,我們使用組合替換了深度繼承層次結(jié)構(gòu),使代碼更易于理解和維護(hù)。我們創(chuàng)建了小型可重用的 Composable 函數(shù),而不是從多個(gè)父類繼承,可以組合這些函數(shù)來實(shí)現(xiàn)所需的功能。這種方法更加靈活,并遵循 Jetpack Compose 的原則。

3. 硬編碼值或“魔法數(shù)字”:

硬編碼值可能會(huì)使代碼不夠靈活,難以維護(hù)。使用常量或資源文件存儲(chǔ)可能會(huì)發(fā)生更改的值。
示例:
在 Jetpack Compose 中,我們不使用像 colors.xml、dimens.xml 和 strings.xml 這樣的 XML 文件。相反,我們?cè)?Kotlin 文件中定義這些資源。以下是一個(gè)使用硬編碼值的示例,并對(duì)其進(jìn)行重構(gòu)以使用常量:

硬編碼代碼示例:

import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun HardcodedValuesExample() {
    Text(
        text = "Hello, World!",
        color = Color(0xFF3F51B5),
        modifier = Modifier.padding(16.dp)
    )
}

使用常量進(jìn)行重構(gòu):
創(chuàng)建一個(gè)專門的文件,例如Theme.kt

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

object Constants {
    val primaryColor = Color(0xFF3F51B5)
    val defaultPadding = 16.dp
}

更新 HardcodedValuesExample 使用常量:

import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import Constants.primaryColor
import Constants.defaultPadding

@Composable
fun RefactoredValuesExample() {
    Text(
        text = "Hello, World!",
        color = primaryColor,
        modifier = Modifier.padding(defaultPadding)
    )
}

在重構(gòu)的示例中,我們使用在專門的文件中定義的常量來代替硬編碼的值。這使得代碼更易于維護(hù)和更新。對(duì)于文本字符串,您可以使用類似的方法,在單獨(dú)的文件中定義字符串常量,并在您的 Composables 中使用它們。

4. 長(zhǎng)方法或類:

長(zhǎng)方法或類難以理解和維護(hù)。將它們拆分成更小、更集中的功能單元。
示例:
使用 Kotlin 和 Jetpack Compose,我們有一個(gè) ViewModel 類,其中包含一個(gè)長(zhǎng)方法,處理數(shù)據(jù)轉(zhuǎn)換和業(yè)務(wù)邏輯。我們將通過將方法拆分為更小、更專注的函數(shù)來進(jìn)行重構(gòu)。
長(zhǎng)方法示例:

class LongMethodViewModel : ViewModel() {
    // ...

    private fun processData(data: List<DataItem>): List<ProcessedDataItem> {
        // Step 1: Filter the data
        val filteredData = data.filter { item ->
            item.isActive && item.value > 10
        }

        // Step 2: Transform the data
        val transformedData = filteredData.map { item ->
            ProcessedDataItem(
                id = item.id,
                displayName = "${item.name} (${item.value})",
                important = item.value > 50
            )
        }

        // Step 3: Sort the data
        val sortedData = transformedData.sortedByDescending { item ->
            item.important
        }

        return sortedData
    }
}

重構(gòu)成更小更專一的代碼:

class RefactoredViewModel : ViewModel() {
    // ...

    private fun processData(data: List<DataItem>): List<ProcessedDataItem> {
        return data.filter(::filterData)
            .map(::transformData)
            .sortedByDescending(::sortData)
    }

    private fun filterData(item: DataItem): Boolean {
        return item.isActive && item.value > 10
    }

    private fun transformData(item: DataItem): ProcessedDataItem {
        return ProcessedDataItem(
            id = item.id,
            displayName = "${item.name} (${item.value})",
            important = item.value > 50
        )
    }

    private fun sortData(item: ProcessedDataItem): Boolean {
        return item.important
    }
}

在重構(gòu)的例子中,我們將長(zhǎng)的processData方法分解為更小、更專注的函數(shù):filterData、transformData和sortData。這使得代碼更易于理解、測(cè)試和維護(hù)。

5. 強(qiáng)耦合:

高度依賴彼此的類或組件可能會(huì)使修改或測(cè)試代碼變得困難。通過設(shè)計(jì)具有良好定義接口和最小依賴關(guān)系的組件來實(shí)現(xiàn)松耦合。
例子:
使用Kotlin和Jetpack Compose,ViewModel和Composable函數(shù)之間存在強(qiáng)耦合。我們將使用StateFlow重構(gòu)它以實(shí)現(xiàn)松耦合。
強(qiáng)耦合例子:

class TightCouplingViewModel : ViewModel() {
    val data = mutableStateOf(listOf<DataItem>())

    init {
        loadData()
    }

    private fun loadData() {
        // Load data...
        data.value = loadedData
    }
}

@Composable
fun TightCouplingExample(viewModel: TightCouplingViewModel) {
    val data = viewModel.data.value
    LazyColumn {
        items(data) { item ->
            // Display data item...
        }
    }
}

使用松散耦合進(jìn)行重構(gòu):
更新 ViewModel 以使用 StateFlow:

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class LooseCouplingViewModel : ViewModel() {
    private val _data = MutableStateFlow(listOf<DataItem>())
    val data: StateFlow<List<DataItem>> = _data

    init {
        loadData()
    }

    private fun loadData() {
        // Load data...
        _data.value = loadedData
    }
}

更新 Composable 函數(shù)以觀察來自 ViewModel 的數(shù)據(jù):

import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue

@Composable
fun LooseCouplingExample(viewModel: LooseCouplingViewModel) {
    val data by viewModel.data.collectAsState()
    LazyColumn {
        items(data) { item ->
            // Display data item...
        }
    }
}

在重構(gòu)的示例中,我們通過使用StateFlow來觀察和響應(yīng)ViewModel中數(shù)據(jù)的變化,實(shí)現(xiàn)了ViewModel和Composable函數(shù)之間的松耦合。這種方法使得修改或測(cè)試代碼更容易,因?yàn)閂iewModel和UI組件不會(huì)直接引用彼此。

結(jié)論

總之,在Android開發(fā)中解決五大代碼壞味道有助于創(chuàng)建更清晰、更高效、更高質(zhì)量的代碼庫。通過遵循Jetpack Compose UI和MVVM架構(gòu)的最佳實(shí)踐,開發(fā)人員可以創(chuàng)建具有模塊化、可維護(hù)和可測(cè)試性的應(yīng)用程序。

  1. 通過將大型類分解為更小、更集中的功能單元,實(shí)現(xiàn)避免過多使用god對(duì)象,并實(shí)現(xiàn)存儲(chǔ)庫模式。
  2. 通過組合取代深層繼承層次結(jié)構(gòu),創(chuàng)建更小、可重用的可組合項(xiàng)或混合項(xiàng),以實(shí)現(xiàn)所需的功能。
  3. 通過將硬編碼的值或“神奇數(shù)字”替換為常量或資源文件,使代碼更具靈活性和可維護(hù)性。
  4. 通過將長(zhǎng)方法或類分解為更小、更集中的功能單元,使其更易于理解、測(cè)試和維護(hù)。
  5. 通過設(shè)計(jì)具有良好定義接口和最小依賴關(guān)系的組件、使用LiveData或StateFlow來觀察和響應(yīng)ViewModel中的數(shù)據(jù)變化,并避免ViewModel和UI組件之間的直接引用,實(shí)現(xiàn)松耦合。
    通過解決這些代碼壞味道,您可以增強(qiáng)開發(fā)過程,改善可維護(hù)性,并創(chuàng)建提供優(yōu)秀用戶體驗(yàn)的Android應(yīng)用程序。

參考

https://medium.com/@fauzisho/top-5-code-smells-in-android-development-jetpack-compose-ui-and-mvvm-e3934ddbc14c文章來源地址http://www.zghlxwxcb.cn/news/detail-434018.html

到了這里,關(guān)于Android開發(fā)中的前五個(gè)代碼異味:Jetpack Compose UI和MVVM的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 對(duì)于Android開發(fā),我們?yōu)楹我獙W(xué)Jetpack Compose?

    對(duì)于Android開發(fā),我們?yōu)楹我獙W(xué)Jetpack Compose?

    Jetpack Compose 是用于構(gòu)建原生 Android 界面的新工具包。它可簡(jiǎn)化并加快 Android 上的界面開發(fā),使用更少的代碼、強(qiáng)大的工具和直觀的 Kotlin API,快速讓應(yīng)用生動(dòng)而精彩。Compose 使用全新的組件——可組合項(xiàng) (Composable) 來布局界面,使用修飾符 (Modifier) 來配置可組合項(xiàng)。 為何Jetp

    2024年02月10日
    瀏覽(97)
  • 編程之道:【代碼重構(gòu)】消除異味和壞味道,提升代碼質(zhì)量

    在軟件開發(fā)中,有時(shí)會(huì)遇到一些讓人不爽的情況,代碼也不例外。這些情況被稱為“代碼異味”或“壞味道”。它們可能表明代碼存在問題,需要進(jìn)行重構(gòu)以提升質(zhì)量和可維護(hù)性。本文將介紹代碼異味和壞味道是什么,以及如何識(shí)別和解決它們。 代碼異味和壞味道是什么?

    2024年02月10日
    瀏覽(115)
  • Android使用Jetpack WindowManager來開發(fā)可折疊設(shè)備的探索

    Android使用Jetpack WindowManager來開發(fā)可折疊設(shè)備的探索

    我們?cè)贕oogle開發(fā)者大會(huì)上,看到Jetpack WindowManager和WindowSizeClass這些技術(shù),如下圖。 那這里不得不說折疊屏手機(jī)了 在其中一個(gè)顯示區(qū)域中運(yùn)行一個(gè)應(yīng)用。 同時(shí)運(yùn)行兩個(gè)應(yīng)用,各位于一個(gè)顯示區(qū)域中(在 multi-window 模式下)。 可折疊設(shè)備還支持不同的折疊狀態(tài)。折疊狀態(tài)可用來

    2024年02月08日
    瀏覽(25)
  • Android NDK開發(fā)詳解之編寫C/C++代碼中的Android SDK 版本屬性)

    本部分將討論如何使用 NDK 提供的庫。 注意:有關(guān)導(dǎo)入預(yù)構(gòu)建庫(未包含在 NDK 中的庫)的指南已移至各個(gè)構(gòu)建系統(tǒng)的相關(guān)部分。請(qǐng)根據(jù)您的項(xiàng)目需求參閱 CMake 或 ndk-build 指南。 文中說明了 NDK 提供的 C ++ 運(yùn)行時(shí),并介紹了 NDK 提供的其他庫(例如 OpenGL ES 和 OpenSL ES)以及支持

    2024年02月07日
    瀏覽(41)
  • Jetpack:021-Jetpack中的滑動(dòng)列表

    Jetpack:021-Jetpack中的滑動(dòng)列表

    我們?cè)谏弦徽禄刂薪榻B了Jetpack中底部導(dǎo)航欄相關(guān)的內(nèi)容,本章回中主要介紹 滑動(dòng)列表 。閑話休提,讓我們一起Talk Android Jetpack吧! 我們先看一個(gè)場(chǎng)景:大家在使用手機(jī)時(shí)會(huì)打開聯(lián)系人查找某位朋友,由于聯(lián)系人比較多需要上下滑動(dòng)才可以找到這位朋友,顯示這么多聯(lián)系人的

    2024年02月08日
    瀏覽(18)
  • Jetpack:025-Jetpack中的多點(diǎn)觸控事件

    Jetpack:025-Jetpack中的多點(diǎn)觸控事件

    我們?cè)谏弦徽禄刂薪榻B了Jetpack中滾動(dòng)事件相關(guān)的內(nèi)容,本章回中主要介紹 多點(diǎn)解控事件 。閑話休提,讓我們一起Talk Android Jetpack吧! 我們?cè)诒菊禄刂薪榻B的多點(diǎn)觸控事件是指通過多個(gè)手指同時(shí)操作,此時(shí)會(huì)發(fā)出相關(guān)的事件,這些事件包含, 縮放,旋轉(zhuǎn)和平移 。常見的使用

    2024年02月06日
    瀏覽(26)
  • Android Jetpack Compose 別裁

    一、簡(jiǎn)介 二、compose優(yōu)缺點(diǎn) 三、compose好學(xué)嗎 四、Android Jetpack Compose?跟 fluter 哪個(gè)更好 五、Android Jetpack Compose?跟 fluter 技能學(xué)習(xí)選擇 之所以叫Android Jetpack Compose別裁是希望能取舍網(wǎng)上的對(duì)compose的資料,推出別出心裁的文章,文章結(jié)束都會(huì)有一個(gè)案例,通過實(shí)踐學(xué)習(xí),讓學(xué)習(xí)的

    2024年02月03日
    瀏覽(94)
  • Android之簡(jiǎn)單描述jetpack

    Android之簡(jiǎn)單描述jetpack

    把很多變量,邏輯和數(shù)據(jù)擺在我們的Activity和Fragment中,這樣的代碼很混亂,難以維護(hù)。 這樣的開發(fā)模式違反了單一責(zé)任的原則。 而ViewModel可以有效地劃分責(zé)任。 具體的可以用于持有和UI元素相關(guān)的數(shù)據(jù) ,以保證這些數(shù)據(jù)在屏幕旋轉(zhuǎn)時(shí)不會(huì)丟失,以及負(fù)責(zé)和倉庫之間進(jìn)行通訊

    2023年04月20日
    瀏覽(21)
  • Jetpack Compose: Hello Android

    Jetpack Compose: Hello Android

    Jetpack Compose 是一個(gè)現(xiàn)代化的工具包,用于使用聲明式方法構(gòu)建原生 Android UI。在本博文中,我們將深入了解一個(gè)基本的 “Hello Android” 示例,以幫助您開始使用 Jetpack Compose。我們將探討所提供代碼片段中使用的函數(shù)和注解。 在深入代碼之前,請(qǐng)確保您已經(jīng)準(zhǔn)備好使用 Jetpac

    2024年03月10日
    瀏覽(101)
  • Android Jetpack學(xué)習(xí)系列——Navigation

    Android Jetpack學(xué)習(xí)系列——Navigation

    寫在前面 Google在2018年就推出了Jetpack組件庫,但是直到今天我才給重視起來,這真的不得不說是一件讓人遺憾的事。過去幾年的空閑時(shí)間里,我一直在嘗試做一套自己的組件庫,幫助自己快速開發(fā),雖然也聽說過Jetpack,但是壓根兒也沒去了解,但是其實(shí)自己已經(jīng)無形之中用到

    2024年02月02日
    瀏覽(55)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包