数据类
1. 可维护性
- 场景:在数据传输和存储场景下,数据类非常适用。例如在网络请求获取数据后,将数据解析成数据类对象,方便在不同模块间传递。比如,一个电商应用中从服务器获取商品信息,可创建一个
Product
数据类:
data class Product(
val id: Int,
val name: String,
val price: Double
)
- 避免潜在问题:避免在数据类中添加过多业务逻辑,保持其纯粹的数据载体特性,否则会使代码维护变得复杂。例如不要在
Product
数据类中直接编写计算商品折扣价格的业务逻辑,而应在专门的业务逻辑层处理。
2. 扩展性
- 场景:当有新的数据字段需要添加时,数据类很容易扩展。如电商应用后续要展示商品库存,可直接在
Product
类中添加 val stock: Int
字段。
- 避免潜在问题:注意数据类扩展后可能影响到序列化和反序列化逻辑,比如如果使用了
Gson
库进行 JSON 解析,新增字段可能需要调整 Gson
的配置以正确处理新字段。
3. 性能优化
- 场景:数据类在内存占用和访问速度上表现较好。因为数据类默认生成了
equals
、hashCode
和 toString
等方法,在集合操作中使用效率高。例如在一个商品列表 List<Product>
中查找特定商品时,使用 equals
方法可高效判断。
- 避免潜在问题:不要过度创建不必要的数据类实例,特别是在循环中频繁创建,可能导致内存抖动。比如在一个频繁调用的方法中,每次都创建新的
Product
实例用于临时计算,可优化为复用已有的实例。
4. 与 Jetpack 兼容性
- 场景:在 Jetpack 的
ViewModel
中,数据类可很好地用于存储 UI 相关的数据。例如在一个展示商品详情的 ViewModel
中:
class ProductViewModel : ViewModel() {
val productLiveData = MutableLiveData<Product>()
}
- 避免潜在问题:确保数据类遵循 Jetpack 相关组件的生命周期规则,例如不要在数据类中持有可能导致内存泄漏的上下文引用。
密封类
1. 可维护性
- 场景:在处理有限状态和分支逻辑时密封类很有效。例如在一个网络请求状态管理中,可创建如下密封类:
sealed class NetworkState {
object Loading : NetworkState()
data class Success<T>(val data: T) : NetworkState()
data class Error(val message: String) : NetworkState()
}
- 避免潜在问题:在使用
when
表达式处理密封类时,要确保覆盖所有情况,否则编译器会报错。例如:
fun handleNetworkState(state: NetworkState) {
when(state) {
is NetworkState.Loading -> println("Loading...")
is NetworkState.Success -> println("Success: ${state.data}")
// 这里必须添加处理 NetworkState.Error 的分支,否则编译不通过
is NetworkState.Error -> println("Error: ${state.message}")
}
}
2. 扩展性
- 场景:当需要添加新的状态时,在密封类中添加新的子类即可。例如后续添加一个
Retry
状态:
sealed class NetworkState {
object Loading : NetworkState()
data class Success<T>(val data: T) : NetworkState()
data class Error(val message: String) : NetworkState()
object Retry : NetworkState()
}
- 避免潜在问题:添加新状态后,所有使用该密封类的
when
表达式都需要更新以处理新状态,否则可能出现未处理状态的情况。
3. 性能优化
- 场景:密封类的实例数量有限,在内存占用上比较稳定。并且
when
表达式处理密封类在编译期可进行优化,提高执行效率。
- 避免潜在问题:不要在密封类中定义过多复杂的操作,因为密封类主要是为了状态管理,复杂操作可能影响性能和可读性。
4. 与 Jetpack 兼容性
- 场景:在 Jetpack 的
Navigation
组件中,密封类可用于处理导航结果。例如:
sealed class NavigationResult {
object Success : NavigationResult()
object Canceled : NavigationResult()
}
- 避免潜在问题:确保密封类与 Jetpack 组件的交互逻辑清晰,避免出现混淆不同状态导致的导航异常。例如在处理导航结果时,要准确区分
Success
和 Canceled
状态以执行正确的逻辑。