过去的几个月中,在Tuenti上与同行例如@pedro_g_s和@flipper83进行了一些讨论。我决定去写一篇关于Android APP架构的文章。
 
写这个文章的目的是为了向你们展示一些我自己的方法,这些方法已经存在我的脑中好几个月了,主要来自于我自己的学习和研究。
 
开始行动
我们都知道编写高质量的软件是很难的而且很复杂:这不仅仅是满足需求,而应该是健壮的,易维护的,可测试的和可扩展的。所以提出的“简单的架构”理念是一种好的开发任何软件应用的方法。
 
想法很简单:“简洁架构”代表一组实践方式它的系统包含以下内容:
  • 独立的框架
  • 可测试的
  • 独立的UI
  • 独立的数据库
  • 独立的外部机构
并不是必须而且只能用4个圈表示(如图上所示),但是这里有一条从属规则必须知道。这个从属规则是:代码的依赖只能是指向内部的,而且只有内圈能知道外圈的内容。也就是外部的圈是无法知道内部圈的内容的。
 
以下是一些能让我们更好的熟悉和理解这个方法的一些名词解释:
  • Entities:应用的业务对象
  • Use Cases: 也叫交互器。用户实例由与Entities的数据流组成。
  • Interface Adapter:这里设置一些适配器将数据转换成user case 和entities能用的格式。Presenters 和 Controllers 属于这一层。
  • Framework 和Drivers: 这里是真正的实现区域,如:UI,工具,frameworks等等。
 
为了更好的解释,请参考这篇文章视频
 
我们的方案:
我会通过一个简单的例子来解释这个方案;创建一个简单的APP,这个APP实现的功能是:通过后台云来获取朋友或者用户的列表,当用户点击列表中的一项就会显示一个详细的页面。
 
Android架构
目的是为了独立业务单元,业务单元对于外围是未知的,然而这个业务单元能够进行独立测试。
 
我提议将工程分成3层来实现,每层都有自己的目的并与其它层独立。
 
因为每层都有自己的数据模型所以才能实现独立(你可以看到在代码中有一个数据映射表被用来进行完成数据的传送,这个是不想通过整个应用使用公用一套模型的代价)
 
以下是原理图:
注释:我没有使用外部的类库(除了使用gson去解析json数据和junit,mockito,robolectic和espresso 用来测试)。这样做的目的就是为了例子更简洁。另外不要讨厌去添加ORMs去存储硬盘数据或者其他相关的注入框架或者其他的工具或者你熟悉的库。(记住不要重复的制造车轮)
 
Presentation 层
 
呈现者在这层中由inteactors组成,他们在主UI线程之外的线程上工作,然后通过回调函数来传回数据并更新UI。
 
如果你想要一个更好的关于MVP和MVVM在Android UI的影响,可以看这篇文章
 
Domain 层
业务规则在这里,所有的逻辑关系也在这里。查看Android 工程,你会发现所有的Interactors的实现在这里。
这一层由无Android无关的纯Java代码构成。所有外部组件使用接口来对业务块进行联系。
 
Data层
应用中所有的数据都来自这一层,他们通过UserRepository(这个接口在domain层)的实现,使用Repository Pattern的一种策略,通过工厂模式,获取各种不同的数据源取决于中央条件。
 
在实例中,当我们通过Id来获取用户实例的时候,首先会选择磁盘缓存,如果不存在的话会通过网络获取数据然后保存在本地磁盘中。
 
这种机制的前提条件是数据源对于客户端来说是透明的,它不必关系数据是来自内存,磁盘或者是云数据库。只要相信可以获得到数据即可。
注释:在实例中,因为只是为了学习,我通过一个文件系统和android preferences来实现简单和原始的磁盘缓存。再次铭记不要重复造车轮。
 
Error Handling
这个是我们应该总是优先讨论,如果分享你的解决方案会更好。
 
我的策略是使用回调函数,如果一些错误发生在数据库,那么回调会有两个方法onResponse()和onError().第二个方法是会将异常封装在一个叫"ErorBundle"的类中:这个方法会带来一些困难因为存在一个链式的回调,一个接一个的知道错误到了presentation层,但是如果代码写的易读会将这种困难度减低。
另一方面,我会实现一个evetn bus 系统来处理错误事件,这个系统叫GOTO . 在我看来,有时如果订阅太多的事件,但是又没有控制紧密会导致一些事件丢失。
 
Testing
对于测试工作,我选了几种对应不同层的解决方案。
  • Prestation layer:使用android instrumtntation 和espresso去做集成和功能测试。
  • Domain layer:Junit 加mockito 对于单元测试。
  • Data Layer:Robolectric加junit加mockito用于集成和单元测试。
 
代码展示
代码在github上https://github.com/pedrovgs/EffectiveAndroidUI/,对于代码文件夹结构需要说明的是不同的层使用不同的模块。
  • presentation:这是android 模块,代表presetntaion Layer.
  • domain:纯粹的Java模块无任何Android关联。
  • data:获取数据的Android 模块。
  • data-test:针对Data layer的测试。由于使用Robolectric的限制,所以我要单独分离出来。
 
总结:
正如Uncle bob 所说“Architecture is about Intent,not Frameworks".我们在工作中总是会遇到各种挑战,但是如果使用这些技术,对于应用可以做到以下:
  • 易于维护
  • 方便测试
  • 高内聚
  • 低耦合
作为总结我强烈建议你去试试然后分享你的结果和经验。我们相信持续的改进一直是一种好的事情。
 
我希望你能通过本文获得有用的信息。

如何简单的构建Android?的更多相关文章

  1. gradle学习系列之eclipse中简单构建android项目

    看不到图片能够去訪问这个网址看看:http://pan.baidu.com/s/1o6FrFkA 一.什么是Gradle 官网www.gradle.org上介绍Gradle是升级版(evolved)的 ...

  2. 使用Maven构建Android项目

    http://www.ikoding.com/build-android-project-with-maven/ 之前一直在做WEB前端项目,前段时间接手第一个Android项目,拿到代码之后,先试着 ...

  3. 【Android】如何快速构建Android Demo

    [Android]如何快速构建Android Demo 简介 在 Android 学习的过程中,经常需要针对某些项目来写一些测试的例子,或者在做一些 demo 的时候,都需要先写 Activity 然 ...

  4. 用Gradle 构建android程序

    前言 android gradle 的插件终于把混淆代码的task集成进去了,加上最近,android studio 用的是gradle 来构建项目, 下定决心把android gralde 构建项目 ...

  5. 如何构建Android MVVM 应用框架

    概述 说到Android MVVM,相信大家都会想到Google 2015年推出的DataBinding框架.然而两者的概念是不一样的,不能混为一谈.MVVM是一种架构模式,而DataBinding是 ...

  6. gradle构建android项目详解

    1.用Gradle构建 1.1 工程结构 如图所示,这是一个不能更普通的Android的Gradle工程了. 根目录下面的settings.gradle当中主要是用来include子模块的,比如我们这 ...

  7. 使用组件构建Android应用程序

    原文链接:http://android.eoe.cn/topic/android_sdk 应用程序组件 Android's application framework lets you create ...

  8. 使用Gradle构建Android应用内测版本

    在开发应用的过程中,有时候需要比较当前线上版本和正在开发中的版本差异,目前的做法只能是在两个不同的设备上面安装线上版本和开发中的版本,因为当前版本在调试过程中会覆盖旧版本.本文通过使用gradle来构 ...

  9. 使用Gradle构建Android项目

    阅读目录 Gradle是什么? 环境需求 Gradle基本结构 任务task的执行 基本的构建定制 目录配置 签名配置 代码混淆设置 依赖配置 输出不同配置的应用 生成多个渠道包(以Umeng为例) ...

随机推荐

  1. 设计模式 | 装饰模式(decorator)

    定义: 装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 结构:(书中图,侵删) 一个被装饰接口类:从具体类中抽象出来, ...

  2. 结合JDK源码看设计模式——桥接模式

    前言: 在我们还没学习框架之前,肯定都学过JDBC.百度百科对JDBC是这样介绍的[JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Jav ...

  3. 解决Maven环境变量配置后,’mvn’不是内部或外部命令的问题

    1. 前往https://maven.apache.org/download.cgi下载的Maven程序,解压放在一个路径下 2.新建环境变量MAVEN_HOME,赋值:解压路径如:  D:\env\ ...

  4. Python之路【第四篇】:Python基础之函数

    函数的理解 面向过程:根据业务逻辑从上到下垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 函数作用是你的程序有良好的扩展性.复用性. 同样的功能要是用3次以上的话就建议使 ...

  5. Redis入门教程(二)

    推荐阅读: Redis入门教程(一)https://www.cnblogs.com/jichi/p/10285346.html 5. Redis 的数据结构 5.1 Redis 数据结构介绍 redi ...

  6. 【转载】Sqlserver数据库备份的几种方式

    在实际的数据库Sqlserver的运维的过程中,很多时候我们需要做到数据的备份操作,可以做到定时备份,也可以进行手动数据库备份.在实际的过程中,有时候因业务需要备份出完整数据库,而有时候又因为实际业务 ...

  7. Exp4恶意代码分析 20164312 马孝涛

    1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行.  1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,sy ...

  8. .NET Core 时代已经到了,你准备好了吗

    今天很多人都收到了阿里云函数计算支持.NET Core的短信了. 通过访问 https://help.aliyun.com/document_detail/112379.html 你可以看到最新的说明 ...

  9. 开启全民窃听风云——C#智能录音录像录屏程序源码放送!

    ·引子 我这人从小有个坏毛病,就是喜欢偷窥别人隐私.当然,在道德上,我时刻要求自己做一名正人君子,只不过是心理上有这癖好罢了.所以我从小就对窃听.窃视.黑客技术.破解技术等疯狂着迷!实际上这也是我走上 ...

  10. Python 爬虫——抖音App视频抓包

    APP抓包 前面我们了解了一些关于 Python 爬虫的知识,不过都是基于 PC 端浏览器网页中的内容进行爬取.现在手机 App 用的越来越多,而且很多也没有网页端,比如抖音就没有网页版,那么上面的视 ...