91e49329eeb08ab71c15b300286647ca
重学安卓:架构组件 “一致性问题” 全面解析

往期回顾专栏目录更新动态优惠政策版权须知

温馨提示:如果这是第一次接触《重学安卓》,可通过上述链接来访问和快速了解《重学安卓》专栏、获取它的目录、试读内容,以及了解它的最新动态 和 发展状况。

截至目前,专栏已对 体系化文章 做了 1930 余次修订,数十位群友告诉我 受专栏的启发 他们也开启了写作之路。群里不定期会有小伙伴讨论适配问题、分享原创的开源库 和 提供内推机会,订阅后可随时进群交流。

·

注:本文以《Jetpack MVVM 精讲》 以及《GitHub:Jetpack MVVM Best Practice》 作为前置知识,假设小伙伴已完整查阅并吸收了上述内容。

前言

《为你还原一个真实的 Jetpack Lifecycle》篇起,Jetpack MVVM 架构组件系列文章修订至今 已陪伴大家走过 1.5 个年头,

在与小伙伴们 实事求是的交流和互动 中,我们共同演化完善了《脚手架》开发模式 以及《UnPeek-LiveData》《Smooth-Navigation》《Strict-DataBinding》等衍生的开源库。

这期间也时不时有小伙伴私下反馈说,他们已在公司的新项目中用上《脚手架》开发模式。

为什么要提及 “一致性问题”

在谈论架构组件的过程中,我们不免要提及 “一致性” 的概念,这个概念在相当长一段时间里 都没有在 Android 开发领域出现过,

一切缘于 2019 年,我在各大社区发行了《Jetpack MVVM 精讲》篇,“一致性” 的概念 随着该文的传播 而逐步开始走入人们的视野,

其实就和 “内卷” 等词汇一样,“一致性” 并不是一个新词,而是很早就存在于 “软件工程领域”,只是本人因缘巧合,对架构模式十分感兴趣,经由长期的实践、反思、总结、跨界讨论,乃至有幸 为 “所观测到的现象” 匹配了 “相对精确的概括”

在正式开始本文之前,还是要声明一下,任何高度概括的名词,都是为了更方便地指代某个特定现象、为接下来真正要讨论的事情服务,所以若非本着 “实事求是” 地认识问题和解决问题 的心态而来,请调整好心态再来,不然难以踏实学习和有效交流。

文章目录一览

  • 前言
  • 为什么要提及 “一致性问题”
  • 架构组件和 “一致性问题” 的密切关系
  • 到底什么是一致性、什么是一致性问题
  • 关于 “解决一致性问题” 的举一反三
    • Lifecycle 是通过 ____ 来实现 生命周期管理的一致性
    • LiveData 是通过 ____ 来实现 消息同步的一致性
    • DataBinding 是通过 ____ 来实现 视图调用的 null 安全一致性
  • 综上

架构组件和 “一致性问题” 的密切关系

首先这里的 “架构” 特指 “业务架构”,也即在 “业务开发” 的背景下,容易存在各种 “不可预期” 的错误(例如 Crash 或 收到与预期不符的数据),

而这些 “不可预期” 的错误,经由我们长期的观测和交流发现,它们大都是由所谓的 “一致性问题” 所引起,也即 解决了一致性问题,就能最大程度规避这些 “不可预期” 的错误

所以每当提及 “架构组件”,我们就会提及 “是为了解决 xxx 一致性问题” —— “架构组件” 恰好就是为解决这类问题而生的框架

到底什么是一致性、什么是一致性问题

当我们谈论 “一致性” 时,通常是特指 “结果的一致性”,例如 项目中存在多处雷同的代码,当设计因需求发生改变时,我们务必在 修改 A 处的同时,记得修改 B 处。而 “一致性问题” 即,我们 修改 A 处的同时,忘记了修改 B 处

这种因疏忽而导致的不可预期的问题,是十分普遍的,造成疏忽的原因也是千奇百怪的(例如 A 处是同事 A 负责的,B 处是同事 B 负责的,同事 A 事先并不知道同事 B 也 copy 了一份同样的代码,于是在后续修改时就可能疏忽),

所以本着 “求之于势、不责于人” 的态度,对于这类问题,我们不能苛责开发者务必做到 “不疏忽”,而是考虑 通过某种 “神秘的方式” 来在幕后 默默把这些问题给规避

所以简单来说,“一致性问题” 即 潜在的 “结果不一致”,或者通俗地说就是 “改了 A 处,忘了 B 处”;而 “一致性的目标” 即做到 “一处修改,处处生效、处处同步一致。—— ©KunMinX

关于 “解决一致性问题” 的举一反三

那么上述 “神秘的方式” 究竟是什么呢?

经由广泛的观察和提炼,本人发现 “内聚” 这个词刚好能与之匹配。

下面我们就基于这层认识、结合 Jetpack MVVM 架构组件来举一反三,之前阅读过 架构组件系列文章 的小伙伴也可借此机会重温,看看自己对 “一致性” 以及 “一致性问题” 的理解,是否与原文的本义相契合。

Lifecycle 关注的是生命周期管理的一致性

Lifecycle 解决的一致性问题主要体现在哪里呢?—— 体现在生命周期管理。

以 LocationManager 为例,假设项目中 我们在多个 Activity 中都有获取定位信息的需要,传统的办法是,在 LocationManager 中封装好 绑定、解绑、启动、停止 等方法,然后分别在 Activity 的 onResume 和 onPause 节点去调用这些方法,

然而后续 LocationManager 若是有了其他方法,我们不得不为这些 Activity 都改上一遍,而这就埋下了一致性隐患,因为 项目规模变大、交接人员庞杂了以后,总会有疏忽的时候

旧时候解决这类一致性问题的办法是,写个 LocationActivity 基类,有用到 LocationManager 的 Activity 都继承于这个基类,然而 Java 是单继承,这么做势必会使基类变得越来越大,最后不管有用没用的东西都往里塞。

还记得《Activity 的快乐你不懂》篇介绍的,通过 “组合模式” 来对子类屏蔽不必要的功能吗?

—— 组合优于继承,所以这种情况下,解决一致性问题的 更好办法就是 “将生命周期管理的工作 内聚到 LocationManager 组件中 —— 通过让 LocationManager 组件实现 DefaultLifecycleObserver 接口并在 Activity onCreate 时主动将自己添加到 Lifecycle 观察者队列中,这样一旦 Activity 生命周期节点发生变化,这些观察者组件也都能在自己内部收到通知和处理。

top Created with Sketch.