过去的几个月中,在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. JS 各种宽高

    1.window的各种宽高   outerWidth.innerWidth.outerHeight.innerHeight outerHeight 获取浏览器窗口外部的高度(单位:像素).表示整个浏览 ...

  2. Linux安装kubernetes

    使用KUBEADM安装KUBERNETES V1.14.0 一.环境准备      操作系统:Centos 7.5      一台或多台运⾏行行着下列列系统的机器器: ​ Ubuntu 16.04+ ...

  3. Java开发笔记(九十)对象序列化及其读写

    有些时候,开发者想把程序运行过程中的数据临时保存到文件,可是前面介绍的字符流和字节流,要么用来读写文本字符串,要么用来读写字节数组,并不能直接保存某个对象信息,因为对象里面包括成员属性和成员方法,单就 ...

  4. 设计模式 | 工厂方法模式(factory method)

    定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 结构:(书中图,侵删) 一个工厂的抽象接口 若干个具体的工厂类 一个需要创建对象的抽象接口 若干个 ...

  5. 关于json对象的深拷贝

    前两天写程序,有一个是对后台返回的json数据进行整理然后再使用,用到了关于json 的拷贝.我在我的一篇博客中提到过对数组的拷贝.分为深度拷贝,和浅拷贝.这里附上链接 其实对于数组的拷贝是比较简单的 ...

  6. 前端vue系列-起始篇 vue的基本认知

    hi,大家伙,我是佛系大大,很高兴与你们一起沟通,学习,进步. 很久不更新博客了,现在回来再写博客,尽然是有些怀念的感觉,幸福的感觉.因为写博客,内心会很宁静,沉浸在自己的世界中,是很幸福的一件事.当 ...

  7. Windows系统桌面右击反应变慢、卡顿问题解决方法

    博主的电脑是Win10系统,在修改完系统的用户文件夹名后,桌面右击出现了反应卡顿的现象,并且点击输入法,也变得卡顿.问题解决后,于是想简单记录一下. 还是注册表的问题,使用Win+R快捷键,打开运行, ...

  8. python3 函数传参练习 全局变量与局部变量 的理解

    额 还是继续抄一边NLP第二条: 2.一个人不能控制另外一个人   一个人不能改变另外一个人,一个人只能改变自己. 每个人的信念,价值观,规条系统只对本人有效,不应强求别人接守. 改变自己,别人才会有 ...

  9. centos7 ambari2.6.1.5+hdp2.6.4.0 大数据集群安装部署

    前言 本文是讲如何在centos7(64位) 安装ambari+hdp,如果在装有原生hadoop等集群的机器上安装,需要先将集群服务停掉,然后将不需要的环境变量注释掉即可,如果不注释掉,后面虽然可以 ...

  10. Python中的音频和数字信号处理(DSP)

    翻译自Python For Engineers. 1. 创建一个正弦波 在这个项目中,我们将创建一个正弦波,并将其保存为wav文件. 但在此之前,你应该知道一些理论. 频率:频率是正弦波重复一秒的次数 ...