真香警告:就算不封装商业级 SDK,也请务必掌握的 Android 状态管理最佳实践!

2019-07-03 13:29:51 +08:00
 KunMinX

很高兴见到你!

上上周我在掘金碰巧遇到了一篇用设计模式管理状态的文章,一时兴奋不已,在评论区安利了,一直以来我司在封装商业级 SDK 时,使用的十六进制状态管理机制。

原以为会无人对此感兴趣,没想到,留言很快就收到文章作者的回复,并且在评论区耐心地和我探讨了设计模式的 独占式状态机,和十六进制的 复合状态管理 在使用场景上的区别。

遗憾的是,通过评论区的只言片语,并不能让人体会到 十六进制状态管理 的真正魅力。

于是作为回馈,我特地分享了这一篇:当我们封装商业级 SDK 时,我们是怎么使用十六进制来完成状态管理。

😉

此外,是只有封装 SDK 这种大动作,才值得使用十六进制吗?不是的,恰恰相反,正因为 十六进制状态管理是如此地普适,乃至于连封装 SDK 都优先使用这种方式。

考虑到部分读者可能对十六进制本身不太了解,本文会连同十六进制一起介绍。

所以如果阅读完这篇文章,你对 十六进制的状态管理 有了感性的认识,那我的愿望也就达到了。

https://juejin.im/post/5d1a148e6fb9a07ea6488ba3

8064 次点击
所在节点    Android
38 条回复
cizeZSY
2019-07-03 16:06:14 +08:00
这不是很常见的东西吗。。。
quaack
2019-07-03 16:11:39 +08:00
哈哈哈哈营销鬼才,这不是最简单的位运算吗

要是楼主知道各种 bit magic 可能会吹上天吧
quaack
2019-07-03 16:12:30 +08:00
maninfog
2019-07-03 16:15:33 +08:00
很棒的文章,支持一个。
Mithril
2019-07-03 16:16:46 +08:00
上古时代 Windows API 里的各种 HRESULT 不就是这么干的么。。。
xenme
2019-07-03 16:17:37 +08:00
@whileFalse 你这一句就把楼主打醒了。

估计楼主又要写四千字反省下了。
alextang95
2019-07-03 16:19:38 +08:00
感觉我有点歪楼了,抓紧掰回来

1. 给 LZ 的分享精神点赞
2. 反应比较平淡的是见多了就不惊讶了
3. 恰到好处地解决问题的感觉很爽
4. 文章是有点啰嗦哈
5. 1L 讲的是挺棒的啊……

LZ 别 block 我……
lastpass
2019-07-03 16:33:04 +08:00
另外:我再补充一下。为何用二进制的形式存储状态被淘汰,除非是状态特别多,否则大家都不会使用的原因。
因为现代级的 CPU 寄存器非常之多,还有大量的 l1,l2,l3 缓存,这些状态会大部分情况下会被缓存到 cpu 的寄存器。直接从寄存器取数据可比 cpu 从内存里面取快多了。而且,很多时候。我们通常都只需要某个状态。直接取值和算一遍再获得值,后者的效率明显会略低(虽然大部分情况下,这点速度差距可以忽略)
lastpass
2019-07-03 16:35:17 +08:00
当然,更重要的原因是,用二进制存储状态,太特喵不直观,代码阅读起来太费劲了。所以,大家都不愿意使用这个东西。
huijiewei
2019-07-03 17:22:50 +08:00
位运算非要强行扭成 16 进制,写技术文章最好多参考
KunMinX
2019-07-03 17:54:02 +08:00
@maninfog 感谢你的阅读!

@lastpass 感谢你的补充!
no1xsyzy
2019-07-04 10:07:22 +08:00
@mrjiejiejie 编程珠玑里面不是有过了吗?状压存电话号码,何止 64 个状态,是 1,000,000 个以上的状态,全按位压缩。
no1xsyzy
2019-07-04 10:22:15 +08:00
《编程珠玑》( Programming Pearls )
《算法心得:高效算法的奥秘》( Hacker's Delight )
这些方法现在越来越少了,原因:
1. 内存不缺了
2. #28 缓存更快
3. 影响可读性
4. 现在编程语言常常提供 Set 类型,可以兼具高效和可读性

老古董 Pascal 就支持 set of <enumerable>,可以当作位压编译期展开(可能需要看具体实现)。
甚至可以定义 enum 类型然后做集合,不比你这直观得多?
https://en.wikibooks.org/wiki/Pascal_Programming/Sets
no1xsyzy
2019-07-04 10:36:49 +08:00
另一方面,为何采用 8 个 status (无论是 bool 还是位压 int )标记按钮可用性是逻辑上错误的。
不应该上游控制下游,而应该下游因变于上游。
fn (ui:UI).setModeA(){
ui.mode = A; ui.updateButtonsAvailability();
}
// same for modeB, modeC
fn (ui:UI).updateButtonsAvailability(){
for(button in ui.buttons){
button.updateAvailability(mode=ui.mode)
}}
fn (button:Button).updateAvailability(mode:EnumMode){
button.availability = mode in button.availableModes
}
keymao
2019-07-04 11:05:41 +08:00
还是那句话 有事儿说事儿,上来就是这也简单那也存在,人家就是分享点东西而已,有错误可以合理指出,不足之处补正,愿意讨论讨论,不愿意讨论看看关了就完了,来句不甜不咸的很简单书本里有,有啥意思么? 愁了。 讨论问题,能不能别像个小孩一样。
mmdsun
2019-07-05 08:17:52 +08:00
Mark。二进制状态?
nicoljiang
2019-07-05 18:56:01 +08:00
@keymao 可能是因为楼主没管理好读者的预期(标题起的太大)
karllynn
2019-07-06 16:46:43 +08:00
楼主你没学过 C 语言么…

bit flag 是基本知识吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/579615

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX