美团点评Android客户端融合架构演进之路

凌云 关注

收藏于 : 2018-04-04 08:57   被转藏 : 2   

原文:美团点评Android客户端融合架构演进之路


一 背景

点评美团合并之后,业务需要整合,我们部门的几条业务需要往美团平台迁移,为了降低迁移成本,开发和维护成本,以及将来可能要做的单元测试,需要对架构进行相应的调整。之前的代码都堆在Activity或Fragment里面,UI,业务,数据混合在一起,就使得难以单独的复用和扩展、测试。


二 目标

  • 代码复用

  • UI独立

  • 业务独立

  • 数据独立

  • 可测试



公众号:JANiubility


三 简洁架构

这里先引入简洁架构的概念,该架构由Uncle Bob提出,他认为一个架构应该具有以下特性

  • 框架独立性

    架构不应该依赖于现有的library,这样可以让你像工具一样去使用架构,而不是对你的系统添加约束

  • 可测试

    业务逻辑可以在不依赖UI,数据库,网络服务等其它外部因素的情况下进行测试

  • UI独立性

    在不变动系统其它部分的情况下,可以很方便的改变UI,比如,在没有变动任何业务逻辑的情况下web ui可以被替换成console ui

  • 数据库独立性

    可以很自如的在Oracle,SQL Server之间切换,而不涉及业务逻辑

  • 任何外部代理模块的独立性

    业务逻辑应该不需要知道外部世界的任何事情


    下图阐述了一个简洁架构的各个层之间的关系

  • 内层不应该知道外层的任何情况

  • 各层之间通过接口交互

  • 上层依赖下层,但依赖于接口

应用中最重部分就是业务逻辑层。它负责解决应用所真正想解决的问题。该层不包含任何框架相关的代码,因此其代码应该可以在没有模拟器的情况下独立运行。这样,测试、开发和维护业务逻辑代码就要容易很多。而这就是干净架构的主要优势。

下面简单对以上几个概念进行简单的介绍

Entities

数据部分,一个Entity可以是一个带有方法的对象,或者一个数据结构和方法的集合

Use Cases

该层包含了应用特定的业务规则,封装了应用中所有的use cases。这些use cases从entities组装数据流,传递给业务使用。

该层的变更不应该影响到Entities,也不希望该层会被database,UI,或者其它通用框架的外部变化所影响到,该层应该独立于这些部分。

Interface Adapters

该层是一些为了便于use cases和entities的数据转换的适配器。这一层包含GUI的MVC架构,展示层,Views和Controllers都属于该层。models更倾向于在controllers和use cases之间传递的数据结构,然后从use cases传递给Presenter和Views。

上面的这些原则足以构建高内聚,低耦合,可扩展的应用

四 Android架构探索

一个应用基本可以划分为3个部分,UI,业务,和数据,而在移动端来说,更注重UI的展示,复杂的业务通常放在服务端。

针对这3部分,如何进行设计呢?

可以参考上面的基本原则 ,把整个项目拆分成3个不同的层级:

数据层 —  业务层  —  展示层

每一层保持功能独立,上层依赖下层,但依赖于接口,而不是具体。每一层拥有自己的数据模型,做到依赖独立。

4.1 表现层(Presentation Layer)

常见的模式有MVP,MVC,MVVM

表现层除了UI相关逻辑,不应该含有任何逻辑,这一层应该很轻,数据的获取和业务处理应该交给业务层和数据层,Presenter在该层由Use Cases组装,Use Cases会在新的线程执行一个任务并使用一个带有数据的回调用于渲染view,下图是 MVP 架构模块之间的基本关系

4.2 业务层 (Business logic(Domain) Layer)

业务层可能有些模糊,哪些应该属于该层呢?

按照MVP的方式划分,很容易理解的是,所有的业务逻辑放到P中即可。但实际开发中,你会发现,稍微复杂的业务,P层的代码就会变得非常臃肿。我认为P的角色作为业务逻辑的组装更合适。业务逻辑可以进行相应的封装,比如

另外业务层应该是纯java代码,对android平台没有任何依赖,业务层向外暴露接口。

4.3 数据层(Data Layer)

数据层提供了数据源,数据层也可以包括一些简单的数据处理,比如JSON的封装,一些model的转换,外部不关心具体如何获取数据的细节,只向数据层拿数据。比如下面展示了 仓库模式( Repository Pattern )来实现数据层,它的策略是采用工厂模式,传递不同的条件参数,获取不同的数据。

4.4 测试 (Testing)

基于上面的架构,我们更容易进行测试,不同的分层之间完全独立,每一层也有自己相应的测试方案:

  • Presentation Layer:  使用Android自带的 instrumentation  和 espresso  做集成和功能测试。

  • Domain Layer:   JUnit  +  mockito 做单元测试。

  • Data Layer:   Robolectric  (这一层开始有Android相关的依赖)+ junit  + mockito  做单元和集成测试

五 表现层架构

MVC
Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces.*

MVP,MVC,MVVM  都是表现层的一种模式

这些架构相对于传统的开发方式,门槛高些,要想深入掌握和更高层次的理解各个层的职责,需要一定积累,对于一些简单的场景并不是一种好的方案,复杂的业务场景则会从中得到很多好处。

这些模式的好处

  • 关注点分离,职责明确

    o UI – 负责UI的渲染

    o Presenter/controller – 负责响应UI事件并和Model交互

    o Model – 负责业务行为和状态管理

  • 代码重用性

    关注点和责任分离之后,各层独立,可以增加代码的可用性

  • 测试驱动

    易于测试,只要写一个实现了ViewInterface的类即可测试,而不需依赖android平台

  • 隐藏数据访问

    使用这种模式之后,数据的访问代码就被划分到data层

  • 扩展性高,可适配

    将代码分离到Presenter,Controller和Model中,可以更自由的适配

5.1 MVP

这里简单的介绍下MVP的基本元素

  • M:数据实体,封装数据

  • V:视图的渲染,事件的响应

  • P:中间层,作为与M和V通讯的桥梁,组装业务逻辑

在MVP模式里通常包含4个要素

(1)  View : 负责绘制UI元素、与用户进行交互(Activity或Fragment);

(2)  View interface : View需要实现的接口,View通过View interface与Presenter进行交互

(3)  Model : 业务Bean

(4)  Presenter : 作为View与Model交互的纽带,承载了大部分的复杂逻辑

5.2 MVP vs MVC

相同点

  • 分离了不同组件之间的责任,降低了View和Model之间的耦合

不同点

  • MVP中,View与model之间的耦合更低,不容许View直接访问Model,通过Presenter来交互,更加容易进行单元测试,因为View是通过接口来交互

  • 通常View与Presenter的关系是一对一,复杂的View可能有多个Presenter

  • MVC可以决定展示哪个View,Controller依赖于行为,而且可以被多个View共用

5.3 MVP vs MVVM

MVP单项绑定,而MVVM采用双向绑定(data-binding),View的变动,自动反映在 ViewModel,Model的变动也会反映到View中

其实MVP中Model是很轻的,数据的获取和处理属于架构中的数据层和业务层,所以这一点并不是很让人能够理解。

本篇文章主要是对android架构的探索,目前我们采用的是data+domain+MVP这种架构模式。

后期会分享在架构调整中所遇到的问题和经验。

项目

https://github.com/googlesamples/android-architecture

https://github.com/pedrovgs/EffectiveAndroidUI

https://github.com/dmilicic/Android-Clean-Boilerplate

https://github.com/android10/Android-CleanArchitecture

参考文档

Architecting Android…The clean way?

The Clean Architecture

MVC,MVP 和 MVVM 的图示

https://segmentfault.com/a/1190000003966281?utm_source=APP&utm_medium=iOS&utm_campaign=socialShare

MVC or MVP Pattern – Whats the difference?

https://www.zhihu.com/question/30976423/answer/50181505


关于Java和Android 大牛频道

Java和Android大牛频道 是一 个数万人关注的探讨Java和Android开发的公众号,分享和原创最有价值的干货文章, 让你成为这方面的大牛

我们探讨android和Java开发最前沿的技术: android性能优化 ,插件化,跨平台,动态化,加固和反破解等,也讨论设计模式/软件架构 等。由 群来自BAT的工程师组成的团队

关注即送红包,回复:“百度” 、“阿里”、“腾讯” 有惊喜!!!关注后可用入微信群。群里都是来自百度阿里腾讯的大牛。

欢迎关注我们,一起讨论技术,扫描和长按 下方的二维码可快速关注我们。 搜索微信公众号:JANiubility。

公众号: JANiubility


 阅读文章全部内容  
点击查看
文章点评
相关文章
凌云 关注

文章收藏:9198

TA的最新收藏