Algorithm
初看还是比较简单,就是排列组合,可以先用 for 循环实现两个数组之间的组合结果,然后拿前面合并的结果和下一个进行组合,如此即可。有没有更巧妙地办法呢,看了一个用迭代做地题解,感觉还比较简洁:
1 | public List<String> letterCombinations(String digits) { |
Review
The forgotten art of construction
这篇文章主要讲了构造函数的一些最佳实践。开头调侃了下现代程序员写的代码,说二十年前的程序员来看现在程序员写的代码可能会被震惊到。
对于如何优化构造函数参数,提出了几点:
单一职责
如果构造函数需要十个参数,那有很高的几率你的类做了不止一件事情。那多少个参数合适呢,作者引经据典说明少于4个是合适的。另外通过建造者模式来减少构造函数参数数量并不能真正地减少类的复杂性。
提取共同的依赖关系
如果有两个同类的参数,比如两个不同的 scheduler 可以合并为一个:
1
2
3
4
5
6
7
8@MainThreadScheduler private val mainScheduler: Scheduler,
@IOScheduler private val ioScheduler: Scheduler,
interface RxSchedulers {
val io: Scheduler
val computation: Scheduler
val main: Scheduler
}外观模式
有些情况简单地把多个参数包装到一个类里并不适用,可以把相关的参数放到一个外观类中,只暴露出需要的相关方法。
通过接口
一个类可以继承多个接口,可以通过接口来实现外观模式。
用例模式
像 Presenters 或者 ViewModels,会比较复杂,包含多个 repositories。直接把多个 repositories 合并成一个不太合适,可以通过用例模式组合成一个类。这里其实也就是组合优于继承的一个体现。
1
2
3
4
5class ProfileUseCase(
private val userRepository: UserRepository,
private val tracksRepository: TracksRepository,
private val playlistRepository: PlaylistRepository,
)拆分
有时候构造函数参数直接没什么关系,这时候应该回过头来看这个类的职责并开始拆分。基于同一个原因改动的代码应该放在一起,把基于不同原因改动的代码分开。
Tip
这周遇到一个用户反馈的 crash,后台错误信息是
1 | java.lang.NumberFormatException |
这个函数是这样的:
1 | fun getDouble(origin: Double): Double { |
Google 之后发现是在例如德语等语言的系统下,点号会变成为逗号,导致出错。自己切换测试机上的语言也能复现。
将字符串格式化改为 NumberFormat 实现,并指定地区,再切换系统语言就不会受影响了。修改后的函数如下:
1 | fun getDouble(origin: Double): Double { |
这里有个坑提示下,如果处理地数超过了 999,默认会在千分位用逗号去分隔,需要设置成关闭!
1 | nf.setGroupingUsed(false) |
Share
这周看了《文明、现代化、价值投资与中国》上篇,里面对人类文明历史按狩猎、农业和工业定义为了1.0、2.0到3.0三个阶段,其中 1.0和2.0文明的分析和《枪炮、病菌与钢铁》中的比较类型,书中也提到参考了此书。对于3.0文明,作者以1776年的《国富论》发表、《独立宣言》发表和第一台蒸汽机三件事作为现代化的诞生的标志。
作者分析了现代化没有诞生在中国的原因,因为目前的现代化诞生依赖大西洋经济的形成,这个经济最大的特点是在几乎无政府的状态下发展起来的自由市场。显而易见地,当时地中国不具备这样地条件。
作者认为的现代化就是当现代科技余市场经济像结合是所产生的经济无线累进增长的现象。并认为最大的市场最终将成为唯一的市场,任何人、企业、社会、国家,离开这个最大的市场之后就会不断落后,并最终被迫加入。目前的全球化似乎是这样的,不过近期各国保守主义的不断崛起会不会打断这个进程呢?
书中预测中国在未来几十年经济上最核心的变化将是从政府主导的市场经济转变为以政府为辅助的全面自由市场。内需、服务将占GDP主要部分。感觉全面的自由市场应该不太会实现,毕竟体制和西方还是不一样,不过服务占GDP比重提高应该已经是共识了。