写点什么

让工具成为双手的延伸

作者:Zilliz
  • 2021 年 12 月 10 日
  • 本文字数:2734 字

    阅读完需:约 9 分钟

让工具成为双手的延伸

务实的程序员,他们有哪些特质?


他们面临问题时,在解决方案中透露出某种态度、风格、和理念。他们总是越过问题的表面,试着将问题放在更宽泛的大环境下综合考虑。他们为所做的一切负责,责任感驱使着务实派的程序员,在软件的熵中,保持项目的有序。



Thomas 与 Hunt 从 1999 年开始,通过这本颇具影响力的大作,帮助无数客户创造出更好的软件。这本书是技术书籍中的一件「珍品」,需要经年累月一读再读。无论你是新手还是经验丰富的程序员,你都能从这本书中发现乐趣。


通过这本书,你可以学会:


  • 务实的哲学与务实的方法

  • 避免知识重复的陷阱、灵活驾驭基本工具

  • 防范安全漏洞、组建务实的入门套件

  • 写出有弹性、动态、适配性强的代码

  • 无情而有效地做测试

工欲善其事

你可以在 Shell 中启动应用程序、浏览器、编辑器,还可以搜索文件、查询系统状态,并将结果过滤后输出;你可以通过各种方式组合工具——可能连开发者自己都想不到自己当初开发的工具会被这样使用;你还可以通过对 Shell 编程构建出复杂宏指令,来自动化日常工作。有人要问了,在图形界面和集成开发环境(IDE)中,通过点击屏幕也可以完成以上每件事情,而且看上去更加直观,不是吗?


是,也不是。图形界面的好处是「所见即所得」。像是拖拽文件、发送电子邮件、输入信息等这些工作,你完全可以使用图形界面完成。但是,完全使用图形界面,你会错失环境的部分能力——你将无法把常见的任务自动化、无法通过组合工具来定制宏工具。图形界面的局限是,「所见即全部」,如果你想要超出设计者给定的功能,就会碰壁。


在《程序员修炼之道》的「基础工具」一章中,作者鼓励你使用 Shell、加强使用编辑器的能力。怎样才算游刃有余地使用编辑器?作者给出了一个挑战清单,试试看你能能否不使用鼠标和触控板完成上面所有任务?


  • 当编辑文本时,以字符、单词、行、段落为单位移动光标及进行选择

  • 当编辑代码时,在各种语法单元(配对的分隔符、函数、模块……)之间移动

  • 做完修改后,重新缩进代码

  • 用单个指令完成代码块的注释或者取消注释

  • Undo 并 Redo 变更

  • 把编辑窗口切割成多个面板,然后在它们之间跳转

  • 跳转到特定的行号

  • ……


熟悉 Shell 之后,你会发现生产率大幅度提高,某一天你会惊讶地发现,自己十指翻飞,这些工具已成为不假思索的肌肉记忆、这些工具将成为双手的延伸。

优秀设计的精髓

想要可靠地开发软件,让开发项目更容易理解和维护,需要遵循的原则是:在一个系统中,每一处知识都必须单一、明确、权威地表达。让我们来看一个典型的例子:


  def print_balance(account)    printf "Debits:  %10.2f\n", account.debits    printf "Credits: %10.2f\n", account.credits
if account.fees < 0 printf "Fees: %10.2f-\n", -account.fees else printf "Fees: %10.2f\n", account.credits end
printf "———-\n"
if account.balance < 0 printf "Balance: %10.2f-\n", -account.balance else printf "Balance: %10.2f\n", account.balance end end
复制代码


先不说不应该用浮点数保存货币金额,这段代码中至少有三处重复。首先,关于负数处理的地方有一处明显的复制粘贴。通过增加一个判断正负的函数就可以消除这个重复。


其另一个重复是 printf 的调用中,相同字段的格式反复出现。我们固然可以增加一个常量,把这个常量传给每次的调用,但为什么不直接使用已经定义的函数?解决上面两个重复问题,代码现在长这样:


  def format_amount(value)    result = sprintf("%10.2f", value.abs)    if value < 0      result + "-"    else      result + " "    end  end
def print_balance(account) printf "Debits: %s\n", format_amount(account.debits) printf "Credits: %s\n", format_amount(account.credits) printf "Fees: %s\n", format_amount(account.fees) printf " ———-\n" printf "Balance: %s\n", format_amount(account.balance) end
复制代码


如果客户要求在前面的标签和后面的金额之间多加一个空格,该怎么办?让我们继续优化这段代码:


  def format_amount(value)    result = sprintf("%10.2f", value.abs)    if value < 0      result + "-"    else      result + " "    end  end
def print_line(label, value) printf "%-9s%s\n", label, value end
def report_line(label, amount) print_line(label + ":", format_amount(amount)) end
def print_balance(account) report_line("Debits", account.debits) report_line("Credits", account.credits) report_line("Fees", account.fees) print_line("", "———-") report_line("Balance", account.balance) end
复制代码


如果我们需要变更金额的格式,就去修改 format_amount,如果想要变更标签的格式,就去修改 report_line。现在的这段代码相比第一段,更加易于测试和扩展。程序员要努力的方向,应该是孕育出一个容易复用已有事物的环境,而不是重复知识。

在作品上签名

如果你打算跟别人解释你为什么做不完、为什么延期、为什么搞砸,在此之前先等等,听一下自己的内心。讲给你显示器上的橡皮鸭听听,或是先对着猫说一遍。你的那些借口听起来合理吗?还是很愚蠢?你的老板听到会怎样?


务实的程序员应该提供选择、解决问题,而不是找借口。不要说搞不定;解释一下要做什么才能挽回这个局面。是否必须扔掉这些代码呢?和团队讨论下重构的价值吧?你是否需要一点时间来做原型?为了防止错误再次发生,你是否需要清理你的代码、引入更好的测试?作者在书的最后一章指出,如果程序员的代码都是匿名的,可能会滋生粗心和错误,特别是在大型项目中,程序员不免把自己看成是大齿轮上的一个小齿;如果程序员都在作品上签名,又有可能导致合作的问题。务实的程序员不会逃避责任,相反,我们乐于接受挑战,并为自己的工作感到自豪——「这是我写的,我与我的作品同在」,你的签名被认为是质量的标志。当人们在代码上看到你的名字,应当对这份可靠的、经过测试的、专业的工作充满期许。



积累代码量很重要,

读书、读好书也很重要。

「Zilliz 好书推荐」栏目,

旨在与你分享技术成长相关的书籍,

与你一起先把书读厚,再把书读薄。

——————————————————————————


Zilliz 以重新定义数据科学为愿景,致力于打造一家全球领先的开源技术创新公司,并通过开源和云原生解决方案为企业解锁非结构化数据的隐藏价值。

Zilliz 构建了 Milvus 向量数据库,以加快下一代数据平台的发展。Milvus 数据库是 LF AI & Data 基金会的毕业项目,能够管理大量非结构化数据集,在新药发现、推荐系统、聊天机器人等方面具有广泛的应用。

用户头像

Zilliz

关注

Reinvent data science 2021.10.09 加入

还未添加个人简介

评论

发布
暂无评论
让工具成为双手的延伸