网易首页 > 网易号 > 正文 申请入驻

关于Android架构,你是否还在生搬硬套?

0
分享至

前言

关于Android架构,可能在很多人心里一直都是虚无缥缈的存在,似懂非懂、为了用而用、处处生搬硬套,这种情况使用的意义真的很有限。本人有多个项目架构的经验,恰好对设计领域较为感兴趣,今天我将毫无保留的将自己对架构、设计的理解分享给大家。

本文不会具体去讲什么是MVC、MVP、MVVM,但我描述的点应该都是这些模式的基石,从本质上讲明白这样做,为什么这样做的好处是什么,有了这些底层思想的支持再去看对应的架构模式,相信会让你有一种焕然一新的感觉。

知识储备:需掌握Java面向对象、六大设计原则,如果不理解也无妨,我尽量将用到的设计原则加以详细描述

目录
  • 1. 模块化的意义何在?
    • 1.1 基本概念以及底层思想
    • 1.2 我们要基于哪些特性去做模块化划分?
    • 1.3 Android如何做分层处理?
    • 1.4 Data Mapper或许是解药
    • 1.5 无处安放的业务逻辑
  • 2. 合理分层是给 数据驱动UI 做铺垫
    • 2.1 什么是 控制反转?
    • 2.2 什么是数据驱动UI?
    • 2.3 为什么说数据驱动UI底层思想是控制反转?
    • 2.4 为什么要引入Diff?
  • 3. 为什么我建议使用 函数式编程
    • 3.1 什么是 函数式编程?
    • 3.2 Android视图开发可以借鉴函数式编程思想

1. 模块化的意义何在?

1.1 基本概念以及底层思想

所有的模块化都是为了满足单一设计原则 (字面意思理解即可),一个函数或者一个类再或者一个模块,职责越单一复用性就越强,同时能够间接降低耦合性

在软件工程的背景下,改动就会有出错的可能,不要说“我注意一点就不会出错”这种话,因为人不是机器。我们能做的就是尽可能让模块更加单一,职责越单一影响到外层模块的可能性就越小,这样出错的概率也就越低。

所以模块化核心思想即:单一设计原则

1.2 我们要基于哪些特性去做模块化划分?

做模块化处理的时候尽量基于两种特性进行、功能特性、业务特性

功能特性

网络、图片加载等等都可称之为功能特性。比如网络:我们可以将网络框架的集成、封装等等写到同一个模块(module、package等)当中,这样可以增强可读性(同一目录一目了然)、降低误操作概率,方便于维护也更加安全。同时也可将模块托管至远程如maven库,可供多个项目使用,进一步提升复用性

业务特性

业务特性字面意思理解即可,就是我们常常编写的业务,需要以业务的特性进行模块划分

为什么说业务特性优先级要高于功能特性?

举个例子如下图:

相信很多人见过或者正在使用这种分包方式,在业务层把所有的Adapter、Presenter、Activity等等都放在对应的包中,这种方式合理吗?先说答案不合理,首先这已经是在业务层,我们做的所有事情其实都在为业务层服务,所以业务的优先级应该是最高的,我们应当优先根据业务特性将对应的类放入到同一个包中。

功能模块核心是功能,应当以功能进行模块划分。业务模块核心是业务,应当优先以业务进行模块划分,其次再以功能进行模块划分。

1.3 Android如何做分层处理?

前端开发其实就是做数据搬运,再展示到视图中。数据与视图是两个不同的概念,为了提高复用性以及可维护性,我们应当根据单一设计原则我们应当将二者进行分层处理,所以无论是MVC、MVP还是MVVM最核心的点都是将数据与视图进行分层。

绊脚石:

通常来讲,我们通过网络请求拿到数据结构都是后端定义的,这也就是意味着视图层不得不直接使用后端定义的手段,一旦后端进行业务调整会被迫使我们前端从数据层-->视图层都会进行对应的改动,如下伪代码所示:

起初我们的textView显示的是model中的title,但后端调整后我们需要在model中加一个prefix字段,同时textView显示内容也要做一次字符串拼接。视图层因为数据层的改动而被动做了修改。既然做了分层我们想要的肯定是视图、数据互不干扰,如何解决?往下看...

1.4 Data Mapper或许是解药

Data Mapper是后端常用的一个概念,一般情况下他们是不会直接使用数据库里面的字段,而是加一个Data Mapper(数据映射)将数据库表转按需换成Java Bean,这样做的好处也很明显,表结构甭管怎么折腾都不会影响到业务层代码。 对于前端我觉得可以适当引入Data Mapper,将后端数据转换成本地模型,本地模型只与设计图对应,将后端业务与视图完全隔离。这也就解决了

1.3 面临的问题,具体方式如下:

LocalModel相当于一个中间层,通过适配器模式将数据层与视图层做隔离。 前端引入Data Mapper后可以脱离后端进行开发,只要需求明确就可以做视图层的开发,完全不需要担心后端返回什么结构、字段。并且这种做法是一劳永逸的,比如后端需要对某些字段做调整,我们可以不暇思索直奔数据层,涉及到的调整100%不会影响到视图层

注意点:

  • 当下有一部分公司为了将前后端分离更彻底,由前端开发人员提供Java Bean(相当于LocalModel)的结构,好处也很明显,更多的业务内聚到后端,很大程度提升了业务的灵活性,毕竟App发一次版成本还是比较大的。面对这种情况我们其实没必要再编写Data Mapper。所以任何架构设计都要结合实际情况,适合自己的才是最好的。

1.5 无处安放的业务逻辑


关于业务逻辑其实是一个很笼统的概念,甚至可以将任意一行代码称之为业务逻辑,如此宽泛的概念我们该如何去理解?我先大致将它分为两个方面:

  • 界面交互逻辑:视图层的交互逻辑,比如手势控制、吸顶悬浮等等都是根据业务需要实现的,所以严格来说这部分也属于业务逻辑。但这部分业务逻辑一般在视图层实现。

  • 数据逻辑:这部分是大家常说的业务逻辑,属于强业务逻辑,比如根据不同用户类型获取不同数据、展示不同界面,加上Data Mapper一系列操作其实就是给后端兜底,帮他们补全剩余逻辑而已。为了方便大家理解下文我将数据逻辑统称为业务逻辑。

前面我们说到,Android开发应该具备数据层跟视图层,那业务逻辑放在哪一层比较合适呢?比如MVVM模式下大家都说将业务逻辑放到ViewModel处理,这么说也没有太大的问题,但如果一个界面足够复杂那对应的ViewModel代码可能会有成百上千行,看起来会很臃肿可读性也非常差。最重要的一点这些业务很难编写单元测试用例。

关于业务逻辑我建议单独写一个use case处理。

use case通常放在ViewModel/Presenter与数据层之间,业务逻辑以及Data Mapper都应该放在use case中,每一个行为对应一个use case。

这样就解决了ViewModel/Presenter臃肿的问题,同时更方便编写测试用例。

注意点:

好的设计都是特定场景解决特定问题,过度设计不仅解决不了任何问题反而会增加开发成本。以我目前经验来看Android开发至少一半的场景都很简单:请求-->拿数据-->渲染视图最多再加个Data Mapper,流程很单一并且后期改动的可能也不太大,这种情况就没必要写一个use case,Data Mapper扔到数据层即可

2. 合理分层是给 数据驱动UI 做铺垫

先说结论:数据驱动UI的本质是控制反转

2.1 什么是 控制反转?

控制即对程序流程的控制,一般由我们开发者承担,此过程为控制。但开发者是人所以不可避免出现错误,此时可以将角色做一个反转由成熟的框架负责整个流程,程序员只需要在框架预留的扩展点上,添加跟自己的业务代码,就可以利用框架来驱动整个程序流程的执行,此过程为反转。

控制反转概念和设计原则中的依赖倒置很相似,只是少了一个依赖抽象。

打个比方:

现有一个HTTP请求的需求,如果想自己维护HTTT链接、自己管理TCP Socket、自己处理HTTP缓存.....就是整个HTTP协议全部自己封装,先不说这个工程能不能靠个人实现,就算实现也是漏洞百出,此时可以换个思路:通过OkHttp去实现,OkHttp是一个成熟的框架用它基本上不会出错。个人封装HTTP协议到使用OkHttp框架,这个过程在控制HTTP的角色上发生了一个反转,个人--->成熟的框架OkHttp即控制反转,好处也很明显,框架出错的概率远低于个人

2.2 什么是数据驱动UI?

通俗一点说就是当数据改变时对应的UI也要跟着变,反过来说当需要改变UI只需要改变对应的数据即可。现在比较流行的UI框架如Flutter、Compose、Vue其本质都是基于函数式编程实现数据驱动UI,它们共同的目的都是为了解决数据,UI一致性问题。

在当前的Android中可以使用DataBinding实现同样的效果,以Jetpack MVVM为例:ViewModel从Repository拿到数据暂存到ViewModel对应的ObservableFiled即可实现数据驱动UI,但前提是从Repository拿到的数据可以直接用,如果在Activity或者Adapter做数据二次处理再notify UI,已经违背数据驱动UI核心思想。

所以想实现数据驱动UI必须要有合理的分层(UI层拿到的数据无需处理,可以直接用),Data Mapper恰好解决这一问题,同时也可规避大量编写BindAdapter的现状。 DataBinding并非函数式编程,它只是通过AbstractProcessor生成中间代码,将数据映射到XML中。

2.3 为什么说数据驱动UI底层思想是控制反转?

当前Android生态能实现数据绑定UI的框架只有两个:DataBinding、Compose(暂不讨论) 在引入DataBinding之前渲染一条数据通常需要两步,如下:

共需要两步更改数据源、更改UI,数据源跟UI有一个忘记修改便会出现BUG,千万不要说:“两个我都不会忘记修改”,当面临复杂的逻辑以及十几个甚至几十个的数据源很难保证不出错。

这种问题可以通过DataBinding解决,只需更改对应的ObservableFiledUI便会同步修改,控制UI状态也从个人反转到的DataBinding,个人疏忽的事情DataBinding可不会。 所以说数据驱动UI底层思想是控制反转

2.4 为什么引入Diff?

引入diff之前:

RecyclerView想要实现动态删除、添加、更新需要分别手动更新数据和UI,这样在中间插了一道并且分别更新数据和UI已经违背了前面所说的数据驱动UI,而我们想要的是不管删除、添加或者更新只有一个入口,只要改变数据源就会驱动UI做更新,想要满足这一原则只能改变数据源后对RecyclerView做全部刷新,但这样会造成性能问题,复杂的界面会感到明显的卡顿。

引入diff之后:

Diff算法通过对oldItem和newItem做差异化比对,会自动更新改变的item,同时支持删除、添加的动画效果,这一特性解决了RecyclerView需要实现数据驱动UI的性能问题

3.1 什么是 函数式编程?

  • 一个入口,一个出口。
  • 不在函数链内部执行与运算本身无关的操作
  • 不在函数链内部使用外部变量(实际上这一条很难遵守,可以适当突破)

说的通俗点就是给定一个初始值,经过函数链的运行会得到一个目标值,运算的过程中外部没有插手的权限,同时不做与本身无关的操作,从根本上解决了不可预期错误的产生。

举个例子:

上面这种链式编程就是标准的函数式编程,输入到输出之间开发者根本没有插手的机会(即Log.i(··)之前开发者没有权限处理list),所以整个流程是100%安全的,RxJava、Flow、链式高阶函数都是标准的函数式编程,它们从规范层面解决数据安全问题。所以我建议在Kotlin中 碰到数据处理尽量使用链式高阶函数(RxJava、Kotlin Flow亦然)。

其实函数式编程的核心思想就是 门面模式 以及 迪米特法则

3.2 Android视图开发可以借鉴函数式编程思想

Android视图开发大都遵循如下流程:请求-->处理数据-->渲染UI,这一流程可以借鉴函数式编程,将请求作为入口,渲染作为出口,在这个流程中尽量不做与当前行为无关的事(这也要求ViewModel,ViewModel中的函数要符合单一原则)。这样说有点笼统。

下面举个反例:

View层有刷新、加载更多两种行为,load(isRefresh)一个入口,两个出口。面临的问题很明显,修改刷新或加载更多都会对对方产生影响,违反开闭原则中的闭(对修改关闭:行为没变不准修改源代码),导致存在不可预期的问题产生。

可以借鉴函数式编程思想对其进行改进,将ViewModel的load函数拆分成refresh和loadMore,这样刷新和加载更多两种行为、两个入口、两个出口互不干涉,通过函数的衔接形成两条独立的业务链条。 函数式编程可以约束我们写出规范的代码,面对不能使用函数式编程的场景,我们可以尝试自我约束往函数式编程方向靠拢,大致也能实现相同的效果。

综上所述

  • 合理的分层可以提升复用性、降低模块间耦合性
  • Data Mapper 可以让视图层脱离于后端进行开发
  • 复杂的业务逻辑应该写到use case中
  • 数据驱动UI的本质是控制反转
  • 通过函数式编程可以写出更加安全的代码

——end——

不管你是想要转行还是初学、进阶。如果你对Web前端感兴趣,那就进军程序员吧~

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

/阅读下一篇/

作为前端应当了解的Web缓存知识

返回网易首页 下载网易新闻客户端
相关推荐
热点推荐
新一批055挤满造船厂,周边的形势是什么样,解放军心中一清二楚

新一批055挤满造船厂,周边的形势是什么样,解放军心中一清二楚

蒋福伟
2025-04-21 18:05:23
44岁黄宗泽近照曝光!眉毛稀疏、朝天鼻,一股老人味,痞帅感全无

44岁黄宗泽近照曝光!眉毛稀疏、朝天鼻,一股老人味,痞帅感全无

柠檬有娱乐
2025-04-21 09:01:56
波音同意以105.5亿美元出售部分数字航空业务

波音同意以105.5亿美元出售部分数字航空业务

界面新闻
2025-04-22 21:27:18
人体最怕真菌感染,一旦发生说明两点问题,有的很难治疗好转

人体最怕真菌感染,一旦发生说明两点问题,有的很难治疗好转

呼吸科大夫胡洋
2025-04-23 07:08:43
爆料CBA重决定,季后赛变动,辽宁渔翁得利,总冠军又反转

爆料CBA重决定,季后赛变动,辽宁渔翁得利,总冠军又反转

宗介说体育
2025-04-22 15:22:37
古利特:如果安切洛蒂执教巴西,他将面临一项艰巨的任务

古利特:如果安切洛蒂执教巴西,他将面临一项艰巨的任务

懂球帝
2025-04-22 19:45:10
镜报:受惠于降落伞规则,曼联等队将瓜分5100万镑奖金

镜报:受惠于降落伞规则,曼联等队将瓜分5100万镑奖金

雷速体育
2025-04-22 18:43:53
肯爷突认曾与亲戚乱伦! 「帮对方口交到14岁」新歌歌词是真的

肯爷突认曾与亲戚乱伦! 「帮对方口交到14岁」新歌歌词是真的

ETtoday星光云
2025-04-22 16:18:18
孙俪胡杏儿演情敌,一个一件5万起,一个全身5千多,平价却压大牌

孙俪胡杏儿演情敌,一个一件5万起,一个全身5千多,平价却压大牌

界史
2025-04-22 18:00:46
与黄国昌会面,朱立伦背刺蒋万安,蒋万安发声,赵少康炮轰朱立伦

与黄国昌会面,朱立伦背刺蒋万安,蒋万安发声,赵少康炮轰朱立伦

DS北风
2025-04-22 23:02:10
张丰毅深夜痛哭,表达对儿子的歉意,在镜头前喊:这是我亲儿子!

张丰毅深夜痛哭,表达对儿子的歉意,在镜头前喊:这是我亲儿子!

无处不风景love
2025-04-22 08:34:04
合同到期!CBA状元加盟广东有困难,季后赛只发挥1场,杜锋不满意

合同到期!CBA状元加盟广东有困难,季后赛只发挥1场,杜锋不满意

体坛大事记
2025-04-22 11:49:20
被判10年的李天一,改名换姓出狱后,最恶心的一幕还是出现了

被判10年的李天一,改名换姓出狱后,最恶心的一幕还是出现了

小故事娱乐
2025-03-23 12:20:03
大孝子,王楚钦休假陪爸妈逛动物园,穿大拖鞋,头爸驼背苍老不少

大孝子,王楚钦休假陪爸妈逛动物园,穿大拖鞋,头爸驼背苍老不少

二哥聊球
2025-04-22 23:43:50
越南总理定调“谈判不应损害其他市场”,越南股市一度闪崩,随后V型反转

越南总理定调“谈判不应损害其他市场”,越南股市一度闪崩,随后V型反转

界面新闻
2025-04-22 17:01:06
名宿巩晓彬父子3人今夏出征,大儿子加盟新东家,小儿子冲击冠军

名宿巩晓彬父子3人今夏出征,大儿子加盟新东家,小儿子冲击冠军

璞玉话体坛
2025-04-22 19:55:51
“这也配叫前程似锦?”妈妈炫耀家族第一个研究生,被过来人泼水

“这也配叫前程似锦?”妈妈炫耀家族第一个研究生,被过来人泼水

熙熙说教
2025-04-11 20:04:00
闹大了!终于有名人敢于吐槽:孙颖莎王楚钦成绩差,颜值也拉胯

闹大了!终于有名人敢于吐槽:孙颖莎王楚钦成绩差,颜值也拉胯

湖北的老球迷
2025-03-02 13:03:10
酷似刘亦菲老师走红后续!本人安心于教育,回应:我自己觉得不像

酷似刘亦菲老师走红后续!本人安心于教育,回应:我自己觉得不像

小seven的囧囧啊
2025-04-20 17:31:30
国足或再曝大鱼,涉及8500万,昔日国脚,妻子美国人,定居国外

国足或再曝大鱼,涉及8500万,昔日国脚,妻子美国人,定居国外

东球弟
2025-04-22 15:17:14
2025-04-23 10:00:49
爱创乐育
爱创乐育
努力成为别人心中的大神
30文章数 134关注度
往期回顾 全部

科技要闻

特斯拉汽车收入大幅下降 马斯克宣布"回归"

头条要闻

牛弹琴:美国国安部长包被偷 全世界大开眼界

体育要闻

卡子哥和唐斯,还是我们认知中的那个

娱乐要闻

大s儿女回京!张兰气场全开汪小菲谈养老

财经要闻

宜宾银行与五粮液集团频繁关联交易

汽车要闻

捷途山海T2加长版/山海L9等 捷途新车展前亮相

态度原创

教育
时尚
艺术
亲子
房产

教育要闻

教育科学研究院课后服务教师负担调查:近九成的教师认为负担加重

芭蕾运动风、工装风、波嬉风,今年最流行的风格都在这了!

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

亲子要闻

妈妈做了一个小汉堡,儿子看到后开心地不得了。

房产要闻

60+楼盘狂拼特价,海口最新房价曝光!