关于Android架构那些事
刚开始,因为业务比较赶,我们也没有进行比较好的顶层设计,对代码的要求也是最低要求——完成功能开发就行了。这种短期设计也就造成了我们代码的扩展性几乎为零,稍微添加一点新功能,都要大动干戈。在后台系统架构从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上。就如同我上面举的例子一样,可能有些人会觉得,不对吧,不是另外一张图吗?但是当他们继续依赖搜索引擎的时候,他们就会凌乱了,因为有各种逻辑架构图而且各有各的道理,最要命的是没有人会说哪个是错误的。事实上,从你开始寻找他们的模版开始就已经误入歧途了。
关于Android架构那些事的更多相关文章
- 一种更清晰的Android架构(转)
一种更清晰的Android架构 一种更清晰的Android架构 原文链接 : Architecting Android…The clean way? 译者 : Mr.Simple & So ...
- Android架构分析之Android消息处理机制(二)
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中我们看了一个使用Handler处理Message消息的样例,本文我们 ...
- android学习——android架构
android架构:在了解全局的情况下进行细致化的分析才能更有效的学习android的运行原理,才能更深刻的理解android开发: 1.架构图直观 2.架构详解 2.1.Linux Kernel 2 ...
- Android架构分析之使用自定义硬件抽象层(HAL)模块
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:2.3.7_r1 Linux内核版本:android-goldfish-2.6.29 在上一篇博 ...
- Android架构设计和软硬整合完整训练
Android架构设计和软硬整合完整训练 Android架构设计和软硬整合完整训练:HAL&Framework&Native Service&Android Service&a ...
- [Android 泥水匠] Android基础 之一:浅谈Android架构到HelloWorld案例的剖析
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节. 交流QQ群:[编程之美 365234583] ...
- Android架构初探
#一 背景点评美团合并之后,业务需要整合,我们部门的几条业务需要往美团平台迁移,为了降低迁移成本,开发和维护成本,以及将来可能要做的单元测试,需要对架构进行相应的调整.之前的代码都堆在Activity ...
- 一个Android 架构师的成长之路
前言 总所周知,当下流行的编程语言有Java.PHP.C.C++.Python.Go等.其中,稳坐榜首的仍然是Java编程语言,且在以面向对象思想占主导的应用开发中,Java往往成为其代名词.Java ...
- Android架构组件——ViewModel
概述 ViewModel,从字面上理解的话,它肯定是跟视图(View)以及数据(Model)相关的.正像它字面意思一样,它是负责准备和管理和UI组件(Fragment/Activity)相关的数据类, ...
随机推荐
- Linux系统编程——进程间通信(System V IPC 对象)
基本查看命令 ipcs -m查看共享内存 ipcs -s查看信号量 ipcs -q查看消息队列 ipcrm -m id 删除共享内存 -M+key值 ipcrm ...
- jdbc连接远程数据库进行操作
链接远程数据库的时候,要把获得链接的url进行修改 1 package com.test; import java.sql.Connection; import java.sql.DriverMana ...
- 循环select查询结果集
--标记id --每次查询特定列比标记id大的第一条数据, --同时更新标记id,直到查询结果为空 ) set @id='' begin @id=id from T_SGZ where id>@ ...
- numpy及scipy的使用
numpy的使用 把list A转换为numpy 矩阵 np.array(A) np.array(A, 'int32') numpy加载txt文件里面的矩阵 matrix = np.loadtxt(t ...
- MySQL中的内连接、外连接、交叉连接
内连接(INNER JOIN): 分为三种 等值连接.自然连接.不等连接 外连接(OUTER JOIN): 左外连接(LEFT OUTER JOIN或LEFT JOIN) 右 ...
- poj1743 后缀数组, poj挂了 存个代码
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...
- php导出excel时间错误(同一个时间戳,用date得到不同的时间)
通过在date之前设置时区解决了 date_default_timezone_set("Asia/Shanghai"); $schedule_time = date("Y ...
- 按照grouip分组,之后分组调用生成正式凭证 的接口
按照grouip分组,之后分组调用生成正式凭证 的接口 Map<String, List<OperatingLogVO>> resultMap = new HashMap< ...
- Android Theme.AppCompat.Light的解决方法
styles.xml中<style name="AppBaseTheme" parent="Theme.AppCompat.Light">提示如下错 ...
- 洛谷——P2121 拆地毯
P2121 拆地毯 题目背景 还记得 NOIP 2011 提高组 Day1 中的铺地毯吗?时光飞逝,光阴荏苒,三年过去了.组织者精心准备的颁奖典礼早已结束,留下的则是被人们踩过的地毯.请你来解决类似于 ...