刚开始,因为业务比较赶,我们也没有进行比较好的顶层设计,对代码的要求也是最低要求——完成功能开发就行了。这种短期设计也就造成了我们代码的扩展性几乎为零,稍微添加一点新功能,都要大动干戈。在后台系统架构从TCP转为HTTP时,这些缺点则被放大到极致……所以,我们只有重构了。近一个月来,我工作的重心便是好好规划和设计我们项目的代码结构,同时分享给我们的Android组并予以实行。因为研究了很多的架构,其中有Android相关的,也有非Android相关的,但凡稍稍对我设计架构有点点帮助的,我都翻了一遍。甚至还去了解了微信,微博的一些项目架构信息~

  然而在这个过程中,我发现,其实Android并没有像Java后台开发那样有着比较稳定的框架,可以直接套用,基本都是各有各的看法和规则。目前碰到的讨论最多的也就是所谓的MVC、MVP、MVVM这类的MVX框架。为了我们的中心思想做铺垫,那我们来一个个分析一下这些所谓的名门正派到底是不是真的如我们想的那样。

  一、MVC那些事

  我们先来看看MVC,因为MVC经常在Android开发中被提起。我们就先来看看MVC这种结构,通常情况下,也就是你面试的时候回答关于MVC的问题时,用到的答案。

  MVC 通信方式,是环形方式,如下左图所示:View 传送指令到 Controller;Controller 起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变;Model 将新的数据发送到 View,用户得到反馈,所有通信都是单向的。

                 

理论上,还是挺合理的,但实际上,我们很容易就发现了他们耦合的比较深。通常一个改动,基本三大层级都要有改动,因为他们的触发具有很强的连贯性。更具体的情况,就是如果你是真的写代码而不是停在理论上,实际上MVC这种结构更应该用上右图去描述,也就是V的外部连接都是双向的,因为M有需要更改V的需求,同时Controller也有。

  好,我们现在移步到Android,假设我们套用MVC这种架构去处理Android的问题,显然,那一堆XML就是View,而Activity便是所谓的Controller,Model便是我们定义的那些数据对象。但是显然Android里面XML作为View层简直弱得有点螳臂当车的感觉,除了设置点属性,几乎不能做任何逻辑操作。所以,通常我们都会为了增强View的功能,而把Activity+XML作为View层。然而实际上,这样一个组合已经远远超过了View的能力范围了,因为Activity通常也要承担很多逻辑操作,即所谓的Controller的职责……Now we are totally mixed up!因为你已经无法准确分层了。因为MVC的套路主要是应用在强View的开发模式下的,比如桌面应用,因为只要View足够强才能发挥MVC的威力,显然Android原生不具备这个能力,除非你自己写一套View框架,这里说的不是那些什么注入的工具类,那些只是帮你减少代码量而已,并没有从根本上解决这个问题,这里的View框架,是一套增强Android原生View的框架。

  所以,显然原生MVC并不适合直接使用到开发过程中,这里加个原生MVC是针对于“那个标准答案”而言的,因为如果如果你衍生,修正过了就另当别论了~

  二、MVP那些事

  MVP可以说就是从MVC衍生过来,因为有问题就解嘛。既然MVC不够好,那我们就修正它!于是MVP就出来(虽然最初MVP也是如同MVC一样都是应用桌面应用的…)。如下左图所示:

        

  MVP 通信方式:各部分之间的通信,都是双向的;这里View 与 Model 不发生联系,全都通过 Presenter (你喜欢也可以叫Controller~)传递。这种结构便非常适合Android的View层,因为MVP结构中View 非常薄,不部署任何业务逻辑,基本属于”被动视图”(Passive View),即没有任何主动性,当然也就意味着 Presenter会非常的非常厚,所有逻辑都部署在那里。而实际上,我们使用的时候,则更趋于上右图,因为既然Presenter已经责任重大,再多点也没什么事,反而更好统一管理……于是我们便就把Model的能力也削弱一点,也就是Model层完全被动提供数据,类数据库模式。

  我个人认为升级到MVP其实已经挺好的了,至少结构上已经比MVC要更清晰一些了,唯一的问题是我们Presenter有点过重了,还是有改进的地方,我们会在后文一一道来。

  三、MVVM那些破事

  为什么用MVVM那些“破事”呢?因为我们发现至少目前,我没有看到一篇比较正常的关于MVVM在Android上的分析。因为现在Android里面现在一提到MVVM就是Dagger,好像Dagger=MVVM一样……但其实不是这样的,Dagger类工具,仅仅是为了实现View和Model的自动双向绑定而已,也就是本来应该调用view.setXXX去把Model的值赋给View去展示,现在不用了(这个“不用了”,仅仅是说程序员不用显性写这段代码而已……),所以MVVM中所谓的View-Model可以说就是Presenter,只是由于我们有了数据的双向绑定工具后,就使得上图中的Presenter与View的联系变成虚线了,而与Model保持双向连接,Model则与View绑定在一起。所以,与其说MVVM是MVP的优化,不如说是对MVC的优化。MVP和MVVM仅仅是通过两种不同的方式去优化MVC——MVP选择继续分层,而MVVM选择减少分层。也许,你看完上面可能对这些所谓的MVX依然没什么特别的感受。从分割线开始,我们便开始更深入地思考我们遇到的这些问题~


  无论是MVC,MVP还是MVVM,他们更像是一种软件开发的思想而不是一种模式。因为如果你把他定义为模式,你会发现他们在移动端,移动端有分IOS,Android和WP等,还有web端,PC端等实现的方式总是有一定的区别。就比如MVC,有些实现的是一种顺时针的方案,有些则会把mv隔离,全接在C上。就如同我上面举的例子一样,可能有些人会觉得,不对吧,不是另外一张图吗?但是当他们继续依赖搜索引擎的时候,他们就会凌乱了,因为有各种逻辑架构图而且各有各的道理,最要命的是没有人会说哪个是错误的。事实上,从你开始寻找他们的模版开始就已经误入歧途了。

  只有把这些所谓的架构看作是问题的一种解决思想时,我们才可以基于不同平台,不同的业务需求等现实而具体的问题去实现这种思想。说白了就是,马克思主义指导思想很好,但必须要符合中国国情。我们基于以上新的思想再回过头去看看我们之前碰到的问题,是不是很明朗?就比如MVC,无论它有多少中变种,它们都是为了更好地实现MVC分层解偶的理念而已。
  大家去网上搜一下android MVVM,有没有感觉几乎都涉及databinding,然后再介绍一番databinding的用法……然后就没了(稍微补充一下,这个问题你用google又会稍好一点~)。而很显然,基于我们新建立的思想,这些博文可以完全是片面且误人子弟的。因为databinding只是为了实现mvvm这种思想的一个环节的一个工具而已,那就是帮你把view和model绑定起来,如果没有这个工具,你要去实现mvvm的思想,你自己也会写一个binding的Util类去做这件事。其次,绑定完成后,就要操作跟业务息息相关的ViewModel。如果简单,那我们为何需要如此复杂的实现?(大家都知道,我们有些页面其实真的挺简单的,简单到你都不好意思说是你做了~)。如果业务逻辑复杂,你依然需要别的思想去分解这个庞然大物。 
  说这些,既是为了能够让大家多一个角度去看待这些所谓的模式。同时,也是想提醒大家不要太依赖网上的那些搜索,这其中既包括博客也包括github。因为Real大神真的很少,伪大神遍地都是。我们搜索尽量以参考为主,copy为辅。而不是反过来~这里顺便举个例子,如果哪位同学用过itemtouchhelper,并且还网上搜过,你就会发现,整个宇宙就那一个例子(你一搜就知道…),而实际上,只要看一下ItemTouchHelper的源码,你就会发现完全有更友好的办法~
   我们回归正题,那就是所有的软件架构以及开发思想,都是为了四个目的:Maintainable、Testable、Flexible 、Independent。也就是,使软件在满足需求的基础上能够更好地维护、测试、扩展以及相对独立。
  好维护意味着代码结构清晰,便于理解和修改;
  好测试意味着模块相对独立,耦合度低,外部依赖都是保持引用;
  好的扩展意味着接口规范,可以随时延伸业务;
  相对独立意味着与外部系统能相对独立地运行状态;
  其他都好理解,但是什么叫好的独立性?我们假设IOS也是用java开发的,你如何让你这一套代码能够平滑的从Android迁移到iOS?你是不是得定义一个比较好的视图接口以及一些别的涉及到系统API的接口,当迁移到IOS,你只要去实现这些接口就可以让代码正常的运行在IOS系统上。其实说白了就是要把自己的APP当做一个独立系统去开发,就是假设外部依赖都有可能改变,不仅仅是指后台,甚至还包括系统本身。我们都要能够应付得来。
  本来想继续写下去的,但是我想,还是把我的一张PPT放上来作为结束语,让大家慢慢体会吧。因为思想到实践总是会因为实际的环境而有所差异,但是,核心的那些主旨永远都不会变~
             

关于Android架构那些事的更多相关文章

  1. 一种更清晰的Android架构(转)

    一种更清晰的Android架构   一种更清晰的Android架构 原文链接 : Architecting Android…The clean way? 译者 : Mr.Simple & So ...

  2. Android架构分析之Android消息处理机制(二)

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中我们看了一个使用Handler处理Message消息的样例,本文我们 ...

  3. android学习——android架构

    android架构:在了解全局的情况下进行细致化的分析才能更有效的学习android的运行原理,才能更深刻的理解android开发: 1.架构图直观 2.架构详解 2.1.Linux Kernel 2 ...

  4. Android架构分析之使用自定义硬件抽象层(HAL)模块

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:2.3.7_r1 Linux内核版本:android-goldfish-2.6.29 在上一篇博 ...

  5. Android架构设计和软硬整合完整训练

    Android架构设计和软硬整合完整训练 Android架构设计和软硬整合完整训练:HAL&Framework&Native Service&Android Service&a ...

  6. [Android 泥水匠] Android基础 之一:浅谈Android架构到HelloWorld案例的剖析

    作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节. 交流QQ群:[编程之美 365234583] ...

  7. Android架构初探

    #一 背景点评美团合并之后,业务需要整合,我们部门的几条业务需要往美团平台迁移,为了降低迁移成本,开发和维护成本,以及将来可能要做的单元测试,需要对架构进行相应的调整.之前的代码都堆在Activity ...

  8. 一个Android 架构师的成长之路

    前言 总所周知,当下流行的编程语言有Java.PHP.C.C++.Python.Go等.其中,稳坐榜首的仍然是Java编程语言,且在以面向对象思想占主导的应用开发中,Java往往成为其代名词.Java ...

  9. Android架构组件——ViewModel

    概述 ViewModel,从字面上理解的话,它肯定是跟视图(View)以及数据(Model)相关的.正像它字面意思一样,它是负责准备和管理和UI组件(Fragment/Activity)相关的数据类, ...

随机推荐

  1. 关于那些Android中不常用的设置属性

    很多在manifest中的属性我们经常遗忘了它们,或者经常看到但又不是很明白它的作用.那么在这里我就拿了一些属性简单的解释一下,防止以后碰到却不知道其中的意思.不是很全,以后会断断续续的补充吧 一.a ...

  2. MYSQL中INET_ATON()函数

    例如我们现在要在一个表中查出 ip 在 192.168.1.3 到 192.168.1.20 之间的 ip 地址,我们首先想到的就是通过字符串的比较来获取查找结果,但是如果我们通过这种方式来查找,结果 ...

  3. win10网速慢

    升级到win10之后发现网速特别慢,搜了下,网上的解决办法果然好使,按照如下操作即可. 返回桌面,按WIN+R键组合,运行gpedit.msc 打开组策略 依次展开管理模板->网络->Qo ...

  4. hdu 1430(BFS+康托展开+映射+输出路径)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  5. Linux和Windows双系统安装要点

    这里主要说下CentOS和Windows7的双系统安装遇到的一些问题 一.磁盘分区 这个不得不说下在Windows下坑爹的设定了,如果是用默认的磁盘划分,系统会自己先划出一个100M左右的区,关键还是 ...

  6. 前端读者 | 前端构建工具Gulp

    @羯瑞 整理 前言 前端工具现在层出不穷,网上搜下一大片,就看你怎么去使用了,基于项目看用什么样的构建工具.有的工具提供的功能还是非常强大的. FIS.百度团队的产品.现在百度的多个产品中使用.面向前 ...

  7. 将cmake文件转化为vs方便代码阅读与分析

    下面通过“chengxuyuancc”同学的图来说明.通过cmake将winafl cmake编译方式转化为vs2015,方便源码阅读与分析. 1.到官网下载cmake软件.启动图形版 2.选择源码目 ...

  8. 图灵杯 E 简单的RMQ(UVA 11235)(RMQ)

    E: 简单的RMQ 时间限制: 2 Sec  内存限制: 64 MB提交: 934  解决: 165[提交][状态][讨论版] 题目描述 给定一个数组,其中的元素满足非递减顺序.任意给定一个区间[i, ...

  9. oracle中 char,varchar,varchar2的区别

    区别:      1. CHAR的长度是固定的,而VARCHAR2的长度是可以变化的, 比如,存储字符串“abc",对于CHAR (20),表示你存储的字符将占20个字节(包括17个空字符) ...

  10. Visual Studio 2017启动x86的Android模拟器失败

     Visual Studio 2017启动x86的Android模拟器失败 Visual Studio 2017默认提供多个Android模拟器.其中,x86模拟器运行较快.但是由于和Hyper-V服 ...