「安卓高级架构师」教你一种更清晰的 Android 架构,android 原生开发技术
Android 应用架构
这一对象遵循关注分离原则,也就是通过业务规则让内环操作对外环事物一无所知,这样一来,在测试时它们就不会依赖任何的外部元素了。 要达到这个目的,我的建议就是把一个项目分成三个层次,每个层次拥有自己的目的并且各自独立于堆放运作。 值得一提的是,每一层次使用其自有的数据模型以达到独立性的目的(大家可以看到,在代码中需要一个数据映射器来完成数据转换。如果你不想把你的模型和整个应用交叉使用,这是你要付出的代价)。
以下是图解,大家感受下:
注:我并没有使用任何的外部库(除了用于 json 数据句法分析的 gson 和用于测试的 junit, mockito, robolectric 和 espresso 以外)。原因是它可以使这个示例更清晰。总之,在存储磁盘数据时,记得加上 ORM、依赖注入框架或者你熟悉的任何工具或库,这些都会带来很大帮助。(记住:重复制造轮子可不是明智的选择)
表现层 (Presentation Layer)
表现层在此,表现的是与视图和动画相关的逻辑。这里仅用了一个 Model View Presenter(下文简称 MVP),但是大家也可以用 MVC 或 MVVM 等模式。这里我不再赘述细节,但是需要强调的是,这里的 fragment 和 activity 都是 View,其内部除了 UI 逻辑以外没有其他逻辑,这也是所有渲染的东西发生的地方。 本层次的 Presenter 由多个 interactor(用例)组成,Presenter 在 android UI 线程以外的新线程里工作,并通过回调将要渲染到 View 上的数据传递回来。
!
如果你需要一个使用 MVP 和 MVVM 的 Effective Android UI 典型案例,可以参考我朋友 Pedro Gómez 的文章。
领域层 (Domain Layer)
这里的业务规则是指所有在本层发生的逻辑。对于 Android 项目来说,大家还可以看到所有的 interactor(用例)实施。这一层是纯粹的 java 模块,没有任何的 Android 依赖性。当涉及到业务对象时,所有的外部组件都使用接口。
数据层 (Data Layer)
应用所需的所有数据都来自这一层中的 UserRepository 实现(接口在领域层)。这一实现采用了 Repository Pattern,主要策略是通过一个工厂根据一定的条件选取不同的数据来源。 比如,通过 ID 获取一个用户时,如果这个用户在缓存中已经存在,则硬盘缓存数据源会被选中,否则会通过向云端发起请求获取数据,然后存储到硬盘缓存。 这一切背后的原理是由于原始数据对于客户端是透明的,客户端并不关心数据是来源于内存、硬盘还是云端,它需要关心的是数据可以正确地获取到。
注:在代码方面,出于学习目的,我通过文件系统和 Android preference 实现了一个简单、原始的硬盘缓存。请记住,如果已经存在了能够完成这些工作的库,就不要重复制造轮子。
错误处理
这是一个长期待解决的讨论话题,如果大家能够分享各自的解决方案,那真真是极好的。 我的策略是使用回调,这样的话,如果数据仓库发生了变化,回调有两个方法:onResponse()和 onError(). onError 方法将异常信息封装到一个 ErrorBundle 对象中: 这种方法的难点在于这其中会存在一环扣一环的回调链,错误会沿着这条回调链到达展示层。因此会牺牲一点代码的可读性。另外,如果出现错误,我本来可以通过事件总线系统抛出事件,但是这种实现方式类似于使用 C 语言的 goto 语法。在我看来,当你订阅多个事件时,如果不能很好的控制,你可能会被弄得晕头转向。
测试
关于测试方面,我根据不同的层来选择不同的方法:
展示层 ( Presentation Layer) : 使用 android instrumentation 和 espresso 进行集成和功能测试
领域层 ( Domain Layer) : 使用 JUnit 和 Mockito 进行单元测试;
数据层 ( Data Layer) : 使用 Robolectric ( 因为依赖于 Android SDK 中的类 )进行集成测试和单元测试。
代码展示
我猜你现在在想,扯了那么久的淡,代码究竟在哪里呢? 好吧,这就是你可以找到上述解决方案的 github 链接。还要提一点,在文件夹结构方面,不同的层是通过以下不同的模块反应的:
presentation: 展示层的 Android 模块
domain: 一个没有 android 依赖的 java 模块
data: 一个数据获取来源的 android 模块。
data-test: 数据层测试,由于使用 Robolectric 存在一些限制,所以我得再独立的 java 模块中使用。
结论
正如 Bob 大叔 所说:“Architecture is About Intent, not Frameworks” ,我非常同意这个说法,当然了,有很多不同的方法做不同的事情(不同的实现方法),我很确定,你每天(像我一样)会面临很多挑战,但是遵循这些方法,可以确保你的应用会:
易维护
易测试
高内聚
低耦合
最后,我强烈推荐你去实践一下,并且分享你的经验。也许你会找到更好的解决方案:我们都知道,不断提升自己是一件件非常好的事。我希望这篇文章对你有所帮助,欢迎拍砖。
参考资料
Source code: android10/Android-CleanArchitecture · GitHub
The clean architecture by Uncle Bob
Architecture is about Intent, not Frameworks
Model View Presenter
Repository Pattern by Martin Fowler
Android Design Patterns Presentation
总结
Android 从 07 年开始展露头角,到现在已经 13 年了。发展已经比较成熟,现在更多的是技术的沉淀。以及趋势地一个预测,现在给大家献上我的知识脑图。希望对你们有点帮助!
【Android 详细知识点思维脑图(技能树)】
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司 19 年的面试题。把技术点整理成了视频和 PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
点击【Android高级工程师进阶学习】加入我们的圈子领取资料和我们一起吧学习交流吧!【Android 高级工程师进阶系统面试题】:下载链接
Android 进阶学习全套手册
评论