代码之丑
郑晔
开源项目 Moco 作者
19833 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 24 讲
代码之丑
15
15
1.0x
00:00/00:00
登录|注册

13 | 落后的代码风格:使用“新”的语言特性和程序库升级你的代码

你好,我是郑晔。
上一讲,我们讲的是因为代码不一致造成的坏味道,其中我提到的“方案不一致”,是因为随着时间的流逝,总会有一些新的方案产生,替换原有的方案。这其中,最明显的一个例子就是程序设计语言。没有哪门语言是完美的,所以,只要有一个活跃的社区,这门语言就会不断地演进。
从 C++ 11 开始,C++ 开始出现了大规模的演化,让之前学习 C++ 的人感觉自己就像没学过这门语言一样;Python 2 与 Python 3 甚至是不兼容的演化;Java 也是每隔一段时间就会出现一次大的语言演进。
也正是因为语言本身的演化,在不同时期接触不同版本的程序员写出来的程序,甚至不像是在用同一门语言在编程。所以,我们有机会看到在同一个代码库中,各种不同时期风格的代码并存。
通常来说,新的语言特性都是为了提高代码的表达性,减少犯错误的几率。所以,在实践中,我是非常鼓励你采用新的语言特性写代码的。
这一讲,我们就以 Java 为例,讲讲如何使用“新”语言特性让代码写得更好。其实,这里的“新”只是相对的,我准备讨论的是 Java 8 的语言特性,按照官方的标准,这是一个已经到了生命周期终点的版本,只不过,从语言特性上来说,Java 8 是最近有重大变更的一个版本,而很多程序员的编码习惯停留在更早的版本。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何利用“新”的语言特性和程序库升级代码风格,以提高代码表达性和减少错误发生的概率。作者以Java 8的语言特性Optional为例,说明了如何避免空指针异常的问题。通过使用Optional对象容器,可以在取出对象之前判断其是否存在,从而减少“忘记判断”的概率。文章还提到了其他语言如Kotlin或Groovy针对空对象问题的解决方案。总的来说,文章强调了随着语言的不断演进,采用新的语言特性和程序库可以提升代码质量和可维护性。文章还介绍了函数式编程对代码风格的改善,以及如何理解列表转换思维,提高代码表达性。通过讲解新的代码风格,鼓励读者不断学习和改善自己的代码,不停留在过去的编程风格中。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《代码之丑》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • Jxin
    我认为Stream语言设计上有疏忽。 问题: Stream的语意表示一次数据流,或者说一次循环。所以不管是map还是filter都是在这一次循环中每个元素执行的一个job。然而stream却有.parallel()和.sequential()的语意,感觉起来就像是可以随意改变当前这一次数据流的执行方式,但实际上一次数据流只能有一种执行方式。 结论:应该是get出并行的parallelStream()或者get出串行的sequentiaStream(),这样在语意上会更明确些。毕竟执行方式在stream中是一个排他项,他不该被变更。

    作者回复: .parallel()和.sequential(),除非明确地知道执行结果,否则,不要使用。

    2021-01-31
    9
  • Jxin
    1.勘误 Optional<Author> author = book.getAuthor(); String name = author.orElse(null); -> String name = author.map(Author::getName).orElse(null); 原理: 因为Optional内部做了判空处理 好处: 更语意化的表达 个人见解: 这里 author.map(Author::getName).orElse(null); 刚开始用时,会觉得map里面会报空指针的问题,因为在执行map时感觉就会抛出异常。个人认为这有违常规java开发的心智模型。因为java开发习惯了null的存在,因而在map中做空判断,就像是在map中偷偷多做了一件事,有点超出预期?

    作者回复: 多谢提示,已经修改。 心智模型就是要不断提升的。

    2021-01-31
    6
  • 桃子-夏勇杰
    感觉多写了Optional ,代码变得更加累赘了?毕竟这是一种实现细节,如果混在业务代码里面,是不是也是一种坏味道呢?

    作者回复: 看你怎么评价什么算是累赘了,这是一种减少犯错几率的做法,另外,Optional 本身有很多方法可以简化代码的编写。Optional 也是一种需要习惯的构造块,和函数式编程的其它内容是一样的,需要适应一下,适应之后,它就是和 if、for 之类一样的东西。

    2021-01-28
    2
    6
  • Geek_344b93
    我觉得应该是把Optional给封装到一个模型中,然后模型标记可能@Nullable。一来我认为隐藏了于业务无关的空判断,二来,其他调用者不用再写一个相同的判断语句

    作者回复: 如果有更好的 Optional 解决方案,可能是语法的改进,就像 Groovy 和 Kotlin 那样。

    2021-02-08
    3
  • kougazhang
    请教一个问题:业务实践中感觉函数式的扩展性不太好。 比如文中的例子: public ChapterParameters toParameters(final List<Chapter> chapters) { List<ChapterParameter> parameters = chapters.stream() .filter(Chapter::isApproved) .map(this::toChapterParameter) .collect(Collectors.toList()); return new ChapterParameters(parameters); } 这段代码在后续的维护中,经常会出现“后续维护时需要 map 的时候需要加 if 条件,尽早打破循环”的情况。 所以,第一次实现需求时写成老师说的这个样子不难,可是后续随着项目演进还是觉得拆成 for 方便。 这种情况该怎么避免呢?

    作者回复: 本质上,还是不习惯函数式的原语map、filter、reduce,我在《软件设计之美》中专门讲了,不妨去看看。

    2021-11-24
    2
    2
  • NiceBen
    lambda表达式虽然简洁,但是在代码出现bug的时候,不好调试。也许是集合中某个参数问题,但是通过lambda的debug时,没办法精确定位到。

    作者回复: 现在的IDE可以在lambda里设置断点,也还好,不过,还是写测试更好。

    2021-01-28
    2
  • adang
    对于 Optional,在 Ruby 上早期会用 try 后来版本升级改为 &. 写起来很方便。 写 Ruby 的那会儿,有很多程序员是从其它语言转过去的,写出来的代码有很多前一种语言的"烙印",团队 Leader 会要求大家时常翻看 Ruby 的代码规范,规范里有明确要求的严格按照规范来,这样尽量保持代码风格统一。

    作者回复: 这是对的,统一风格很重要,这是上一讲的主题。

    2021-01-28
    2
  • Hobo
    我是写C#的,像这个列表转换在C#中的体现就是Linq吧,不过一些复杂查询我都写的很长😓😓

    作者回复: 不完全是,Linq 的目标是构建一种查询的方式。

    2021-01-28
    1
  • crtmsvc
    非常喜欢这一讲

    作者回复: 可以转发分享给更多的朋友。

    2021-03-06
  • Luke
    我的经验是,只有了解了新语汇解决什么问题,才能改变自己的编写习惯。 不断学习新的代码风格,不仅要知道如何做,也需要掌握新的代码风格是为了解决什么样的问题而产生的,我觉得这一点很重要,就像之前如果不了解 optional 是为了解决 null 忘记判断,或者在Java 语汇中,判断null 比较繁琐而产生的,那么 optional 对于我充其量是一个语法糖。 很多新特性,在读了郑大的解析后,我才从意识上切换了过来。 受益匪浅!
    2021-12-27
    3
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部