通常来讲,我们通过网络请求拿到数据结构都是后端定义的,这也就意味着视图层不得不直接使用后端定义的字段,一旦后端进行业务调整会迫使我们前端从
数据层-->视图层
都会进行对应的改动,如下伪代码所示:
//原始逻辑
数据层
Model{
title
}
UI层
View{
textView = model.title
}
//后端调整后
数据层
Model{
title
prefix
}
UI层
View{
textView = model.prefix + model.title
}
复制代码
起初我们的textView
显示的是model
中的title
,但后端调整后我们需要在model
中加一个prefix
字段,同时textView
显示内容也要做一次字符串拼接。视图层因为数据层的改动而被动做了修改。既然做了分层我们想要的肯定是视图、数据互不干扰,如何解决?往下看…
1.4 Data Mapper或许是解药
Data Mapper
是后端常用的一个概念,一般情况下他们是不会直接使用数据库里面的字段,而是加一个Data Mapper(数据映射)
将数据库表转按需换成Java Bean
,这样做的好处也很明显,表结构甭管怎么折腾都不会影响到业务层代码。
对于前端我觉得可以适当引入Data Mapper
,将后端数据转换成本地模型
,本地模型只与设计图对应,将后端业务
与视图
完全隔离。这也就解决了 1.3 面临的问题,具体方式如下:
数据层
Model{
title
prefix
}
本地模型(与设计图一一对应)
LocalModel{
//将后端模型转换为本地模型
title = model.prefix + model.title
}
UI层
View{
textView = localModel.title
}
复制代码
LocalModel
相当于一个中间层,通过适配器模式
将数据层与视图层做隔离。
前端引入Data Mapper
后可以脱离后端进行开发,只要需求明确就可以做视图
层的开发,完全不需要担心后端返回什么结构
、字段
。并且这种做法是一劳永逸的,比如后端需要对某些字段做调整,我们可以不暇思索直奔数据层
,涉及到的调整100%不会影响到视图层
注意点:
当下有一部分公司为了将前后端分离更彻底,由前端开发人员提供
Java Bean(相当于LocalModel)
的结构,好处也很明显,更多的业务内聚到后端,很大程度提升了业务的灵活性,毕竟App发一次版成本还是比较大的。面对这种情况我们其实没必要再编写Data Mapper
。所以任何架构设计都要结合实际情况,适合自己的才是最好的。
1.5 无处安放的业务逻辑
关于业务逻辑
其实是一个很笼统的概念,甚至可以将任意一行代码称之为业务逻辑
,如此宽泛的概念我们该如何去理解?我先大致将它分为两个方面:
- 界面交互逻辑:视图层的交互逻辑,比如手势控制、吸顶悬浮等等都是根据业务需要实现的,所以严格来说这部分也属于业务逻辑。但这部分
业务逻辑
一般在视图层实现。
- 数据逻辑:这部分是大家常说的业务逻辑,属于强业务逻辑,比如根据不同用户类型获取不同数据、展示不同界面,加上Data Mapper一系列操作其实就是给后端兜底,帮他们补全剩余逻辑而已。为了方便大家理解下文我将
数据逻辑
统称为业务逻辑
。
前面我们说到,Android开发应该具备数据层
跟视图层
,那业务逻辑放在哪一层比较合适呢?比如MVVM
模式下大家都说将业务逻辑
放到ViewModel
处理,这么说也没有太大的问题,但如果一个界面足够复杂那对应的ViewModel
代码可能会有成百上千行,看起来会很臃肿可读性也非常差。最重要的一点这些业务很难编写单元测试用例
。
关于业务逻辑我建议单独写一个use case
处理。
use case
通常放在ViewModel/Presenter
与数据层
之间,业务逻辑以及Data Mapper
都应该放在use case
中,每一个行为对应一个use case
。这样就解决了ViewModel/Presenter
臃肿的问题,同时更方便编写测试用例。
注意点:
好的设计都是特定场景解决特定问题,过度设计不仅解决不了任何问题反而会增加开发成本。以我目前经验来看Android开发至少一半的场景都很简单:
请求-->拿数据-->渲染视图
最多再加个Data Mapper
,流程很单一并且后期改动的可能也不太大,这种情况就没必要写一个use case,Data Mapper
扔到数据层即可。
先说结论:数据驱动UI的本质是控制反转
2.1 什么是 控制反转?
控制
即对程序流程的控制,一般由我们开发者承担,此过程为控制
。但开发者是人所以不可避免出现错误,此时可以将角色做一个反转
由成熟的框架负责整个流程,程序员只需要在框架预留的扩展点上,添加跟自己的业务代码,就可以利用框架来驱动整个程序流程的执行,此过程为反转
。
控制反转
概念和设计原则中的依赖倒置
很相似,只是少了一个依赖抽象
。
打个比方:
现有一个
HTTP请求
的需求,如果想自己维护HTTT链接
、自己管理TCP Socket
、自己处理HTTP缓存
…就是整个HTTP协议
全部自己封装,先不说这个工程能不能靠个人实现,就算实现也是漏洞百出,此时可以换个思路:通过OkHttp
去实现,OkHttp
是一个成熟的框架用它基本上不会出错。个人封装HTTP协议
到使用OkHttp框架
,这个过程在控制
HTTP的角色上发生了一个反转
,个人--->成熟的框架OkHttp
即控制反转,好处也很明显,框架出错的概率远低于个人。
2.2 什么是数据驱动UI?
通俗一点说就是当数据改变时对应的UI也要跟着变,反过来说当需要改变UI只需要改变对应的数据即可。现在比较流行的UI框架如Flutter
、Compose
、Vue
其本质都是基于函数式编程实现数据驱动UI,它们共同的目的都是为了解决数据,UI一致性问题。
在当前的Android中可以使用DataBinding
实现同样的效果,以Jetpack MVVM
为例:ViewModel
从Repository
拿到数据暂存到ViewModel
对应的ObservableFiled
即可实现数据驱动UI,但前提是从Repository
拿到的数据可以直接用,如果在Activity
或者Adapter
做数据二次处理再notify UI
,已经违背数据驱动UI核心思想。所以想实现数据驱动UI必须要有合理的分层(UI层拿到的数据无需处理,可以直接用)
,Data Mapper
恰好解决这一问题,同时也可规避大量编写BindAdapter
的现状。
DataBinding
并非函数式编程,它只是通过AbstractProcessor
生成中间代码,将数据映射到XML中
2.3 为什么说数据驱动UI底层思想是控制反转?
当前Android生态能实现数据绑定UI的框架只有两个:DataBinding、Compose(暂不讨论)
在引入DataBinding之前渲染一条数据通常需要两步,如下:
var title = “iOS”
fun setTitle(){
//第一步更改数据源
title = “Android”
//第二个更改UI
textView = title
}
复制代码
共需要两步更改数据源、更改UI,数据源
跟UI
有一个忘记修改便会出现BUG,千万不要说:“两个我都不会忘记修改
”,当面临复杂的逻辑以及十几个甚至几十个的数据源很难保证不出错。这种问题可以通过DataBinding
解决,只需更改对应的ObservableFiled
UI便会同步修改,控制
UI状态也从个人反转
到的DataBinding
,个人疏忽的事情DataBinding
可不会。
所以说数据驱动UI底层思想是控制反转
2.4 为什么引入Diff?
引入diff
之前:
RecyclerView
想要实现动态删除、添加、更新需要分别手动更新数据和UI,这样在中间插了一道
并且分别更新数据和UI已经违背了前面所说的数据驱动UI
,而我们想要的是不管删除、添加或者更新只有一个入口,只要改变数据源就会驱动UI做更新,想要满足这一原则只能改变数据源后对RecyclerView
做全部刷新,但这样会造成性能问题,复杂的界面会感到明显的卡顿。
引入diff
之后:
Diff
算法通过对oldItem
和newItem
做差异化比对,会自动更新改变的item
,同时支持删除、添加的动画效果,这一特性解决了RecyclerView
需要实现数据驱动UI
的性能问题
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
文末
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,可以来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
这里放上一部分我工作以来以及参与过的大大小小的面试收集总结出来的相关的几十套腾讯、头条、阿里、美团等公司21年的面试专题,其中把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分免费分享给大家,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【延伸Android必备知识点】
这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~
家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
[外链图片转存中…(img-F67Y9nYw-1711826880810)]
【延伸Android必备知识点】
[外链图片转存中…(img-P1Ny4uGz-1711826880810)]
这里只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~