过去的几个月中,在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. Python调用ansible API系列(五)综合使用

    如何把动态生成资产信息.执行playbook以及自定义结果结合起来用呢? #!/usr/bin/env python # -*- coding: utf-8 -*- """ ...

  2. .NET Core之微信支付之公众号、H5支付篇

    前言 本篇主要记录微信支付中公众号及H5支付全过程. 准备篇 公众号或者服务号(并开通微信支付功能).商户平台中开通JSAPI支付.H5支付. 配置篇 公众号或者服务号中 -------开发----- ...

  3. Asp.Net Core 轻松学-基于微服务的后台任务调度管理器

    前言     在 Asp.Net Core 中,我们常常使用 System.Threading.Timer 这个定时器去做一些需要长期在后台运行的任务,但是这个定时器在某些场合却不太灵光,而且常常无法 ...

  4. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  5. 企业移动应用和Smobiler

    www.smobiler.com     什么是企业移动应用?     能够通过一种方式来为客户.合作伙伴和员工交付信息和服务,从而帮助其增加收入,提高业务敏捷性和生产力的移动端产品,我们称之为企业移 ...

  6. 人生苦短,我用 Python

    从2015开始国内就开始慢慢接触Python了,从16年开始Python就已经在国内的热度更高了,目前也可以算的上"全民Python"了.众所周知小学生的教材里面已经有Python ...

  7. Odoo开源智造IT经理人创业圆梦计划正式启动

    概念定义 IT经理人创业圆梦计划是什么? 甲方IT经理人的行业背景 + 其他甲方需求及可靠信任的线索资源 = 自主创业圆梦计划 具体措施 甲方IT经理人的职业行业背景取得其他甲方需求线索及信任——通过 ...

  8. Soot生成代码控制流图

    Soot可以对代码进行分析,提供了多种字节码分析和变换功能,通过它可以进行过程内和过程间的分析优化,以及程序流图的生成,还能通过图形化的方式输出. http://www.brics.dk/SootGu ...

  9. SQLServer之修改数据库架构

    修改数据库架构注意事项 用户与架构完全分离. ALTER SCHEMA 仅可用于在同一数据库中的架构之间移动安全对象. 若要更改或删除架构中的安全对象,请使用特定于该安全对象的 ALTER 或 DRO ...

  10. 查看三种MySQL字符集的方法(转)

    MySQL字符集多种多样,下面为您列举了其中三种最常见的MySQL字符集查看方法,该方法供您参考,希望对您学习MySQL数据库能有所启迪. 一.查看MySQL数据库服务器和数据库MySQL字符集. m ...