有这么一种场景:当我们从服务端请求到数据并转换为实体对象后,UI 界面层需要的却是另一个实体类,比如实际项目场景中:
- case1: 前者实体类是用 Java 编写的,而后者由于某些原因必须使用Kotlin编写的一个实体类,那么就要进行一次类型转换了;
- case2: 前者实体类也是Kotlin 编写的,但是只是最终实体类的一部分数据,最终数据是由多个实体类组合起来的,那么同样需要进行一次类型转换。
- … …
比如下面两个实体类:
@Serializable
data class A(
val id: String,
val name: String = "",
val shortDescription: String = "",
val longDescription: String = "",
val url: String = "",
val imageUrl: String = "",
)
data class B(
val id: String,
val name: String,
val shortDescription: String,
val longDescription: String,
val url: String,
val imageUrl: String,
val followed: Boolean = false,
)
其中A是从服务端获取数据后生成的,而UI界面层使用的是B。如果不想多考虑,那么直接在new B()的时候,将A实例中需要的数据赋值给B实例中的变量即可:
val a: A = ......//假设从服务端生成了A实例
//将A实例中的数据传到B中
val b = B(
id = a.id,
name = a.name,
shortDescription = a.shortDescription,
longDescription = a.longDescription,
url = a.url,
imageUrl = a.imageUrl,
followed = true, //followed从其他数据源获取
)
//接下来就可以将b对象传到UI界面层进行使用了
不知道有没有小伙伴像上面这样使用,反正我写的时候都是直接转:
直到我在学习谷歌的一个Demo项目时,看到了这种写法:
//顶级A扩展函数,将其转换成B
fun A.asEntity() = B(
id = id,
name = name,
shortDescription = shortDescription,
longDescription = longDescription,
url = url,
imageUrl = imageUrl,
followed = true,
)
//使用的地方,如在ViewModel中
suspend fun getA(ids: List<String>?): List<A>{
......
}
//1、第1个地方使用
val result1 : List<B> = network1.getA().map(A::asEntity)
//2、第2个地方使用
val result2 : List<B> = network2.getA().map(A::asEntity)
不得不说这种写法给人眼前一亮的感觉(可能有的大佬早就这样写了😁),A.asEntity()
是一个顶级扩展函数,负责将A实例中的变量值赋给对应的B中,后续有修改可以统一在这里处理;另外顶级函数也意味着可以在任意有需要的地方调用它,比如上述示例的1、 2处都可以调用这个扩展函数,从而达到复用的目的。
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)