authors are vetted experts in their fields and write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Zachary Goldberg
Verified Expert in Engineering

曾任谷歌工程主管和腾讯常驻企业家, 扎卡里是一位经验丰富的专业人士,拥有高管级别的经验.

Expertise

PREVIOUSLY AT

Google
Share

Humans have only been grappling with the art and science of computer programming for roughly half a century. 与大多数艺术和科学相比, 计算机科学在很多方面还只是蹒跚学步, walking into walls, 被自己的脚绊倒, 偶尔还会把食物扔到桌子对面.

因为它相对年轻, 我认为我们还没有就“好代码”的正确定义达成共识, 随着这个定义的不断演变. 有些人会说“好的代码”是具有100%测试覆盖率的代码. Others will say it’s super fast and has a killer performance and will run acceptably on 10-year-old hardware.

虽然这些都是值得称赞的软件开发人员的目标, 然而,我冒昧地提出另一个目标:可维护性. Specifically, “good code” is code that is easily and readily maintainable by an organization (not just by its author!),并且会比它所写的sprint更长久. 以下是我在大公司和小公司担任工程师期间发现的一些事情, 在美国和国外, 这似乎与可维护性有关, “good” software.

永远不要满足于“可以工作”的代码.写出优秀的代码.

第一条:你希望别人的代码如何对待你,你就如何对待你的代码

I’m far from the first person to write that the primary audience for your code is not the compiler/computer, 但下一个要读的人, understand, maintain, 改进代码(六个月后不一定是你). Any engineer worth their pay can produce code that “works”; what distinguishes a superb engineer is that they can write maintainable code efficiently that supports a business long term and have the skill to solve problems simply and in a clear and maintainable way.

在任何编程语言中,都有可能写出好的代码或糟糕的代码. Assuming we judge a programming language by how well it facilitates writing good code (it should at least be one of the top criteria, anyway), 任何编程语言都可以“好”或“坏”,这取决于它是如何被使用(或滥用)的。.

许多人认为“干净”且可读的语言的一个例子是Python. The language itself enforces some level of white space discipline and the built in APIs are plentiful and fairly consistent. 也就是说,创造无法形容的怪物是可能的. For example, one can define a class and define/redefine/undefine any and every method on that class during runtime (often referred to as monkey patching). This technique naturally leads to at best an inconsistent API and at worst an impossible to debug monster. 有人可能会天真地认为,“当然,但没有人这样做。!“不幸的是,他们有,而且不需要花很长时间浏览 pypi 在你遇到实质性(和流行)之前!)库(ab)广泛使用猴子补丁作为其api的核心. I recently used a networking library whose entire API changes depending on the network state of an object. 想象一下,例如,打电话 client.connect() 有时得到一个 MethodDoesNotExist error instead of HostNotFound or NetworkUnavailable.

第二条:好的代码是容易阅读和理解的,无论是部分代码还是整体代码

好的代码易于阅读和理解, in part and in whole, 由他人(以及作者在未来)撰写, trying to avoid the “真的是我写的吗??” syndrome).

我说的"部分"就是这个意思, 如果我在代码中打开某个模块或函数, I should be able to understand what it does without having to also read the entire rest of the codebase. 它应该尽可能地直观和自我记录.

Code that constantly references minute details that affect behavior from other (seemingly irrelevant) portions of the codebase is like reading a book where you have to reference the footnotes or an appendix at the end of every sentence. 你连第一页都看不完!

关于“局部”可读性的其他一些想法:

  • Well encapsulated 代码更容易读懂, separating concerns at every level.

  • Names matter. Activate 思考快与慢system 2 大脑形成思想并付诸实际的方式, 仔细考虑变量和方法的名称. 额外的几秒钟可以带来显著的好处. 一个命名良好的变量可以使代码更加直观, 然而,命名不当的变量可能会导致混淆.

  • 聪明是敌人. 当使用花哨的技巧时, paradigms, 或操作(如列表推导式或三元运算符), 小心地使用它们,使您的代码 more 可读,而不仅仅是更短.

  • 一致性是一件好事. Consistency in style, 包括如何放置大括号,还有操作, 大大提高了可读性.

  • 关注点分离. A given project manages an innumerable number of locally important assumptions at various points in the codebase. 将代码库的每个部分暴露给尽可能少的关注点. 假设您有一个人员管理系统,其中person对象的姓氏有时可能为空. 对于在显示person对象的页面中编写代码的人来说,这可能真的很尴尬! And unless you maintain a handbook of “Awkward and non obvious assumptions our codebase has” (I know I don’t) your display page programmer is not going to know last names can be null and is probably going to write code with a null pointer exception in it when the last name-being null case shows up. Instead handle these cases with well thought out APIs and contracts that different pieces of your codebase use to interact with each other.

Commandment #3: Good Code Has a Well Thought-out Layout and Architecture to Make Managing State Obvious

State is the enemy. Why? Because it is the single most complex part of any application and needs to be dealt with very deliberately and thoughtfully. 常见的问题包括数据库不一致, 局部UI更新,新数据不会到处反映, 无序操作, or just mind numbingly complex code with if statements and branches everywhere leading to difficult to read and even harder to maintain code. 把国家放在一个非常小心的基座上, 并且在如何访问和修改状态方面保持高度一致和深思熟虑, 极大地简化了代码库. 一些语言(例如Haskell)在编程和语法级别强制这样做. 您会惊讶地发现,如果您有类库,您的代码库的清晰度可以提高多少 pure 不访问外部状态的函数, 然后是一小部分引用外部纯功能的有状态代码.

戒律4:好的代码不是重新发明轮子,而是站在巨人的肩膀上

在可能重新发明轮子之前, think about how common the problem is you’re trying to solve or the function is you’re trying to perform. 有人可能已经实现了您可以利用的解决方案. 如果合适的话,花点时间考虑和研究这些选择.

That said, a completely reasonable counter-argument is that dependencies don’t come for “free” without any downside. 通过使用第三方或开源库添加一些有趣的功能, 你正在做出承诺, 变得依赖, that library. That’s a big commitment; if it’s a giant library and you only need a small bit of functionality do you really want the burden of updating the whole library if you upgrade, for example, to Python 3.x? And moreover, 如果遇到错误或希望增强功能, 您要么依赖作者(或供应商)提供修复或增强, or, if it’s open source, find yourself in the position of exploring a (potentially substantial) codebase you’re completely unfamiliar with trying to fix or modify an obscure bit of functionality.

当然,您所依赖的代码使用得越好, 你就不太可能把时间花在维护上. The bottom line is that it’s worthwhile for you to do your own research and make your own evaluation of whether or not to include outside technology and how much maintenance that particular technology will add to your stack.

Below are some of the more common examples of things you should probably not be reinventing in the modern age in your project (unless these ARE your projects).

Databases

Figure out which of CAP 您的项目需要,然后选择具有正确属性的数据库. 数据库不再仅仅意味着MySQL,你可以选择:

  • “传统”模式SQL: Postgres / MySQL / MariaDB / MemSQL / Amazon RDS等.
  • Key Value Stores: Redis / Memcache / Riak
  • NoSQL: MongoDB/Cassandra
  • Hosted DBs: AWS RDS / DynamoDB / AppEngine数据存储
  • Heavy lifting: Amazon MR / Hadoop (Hive/Pig) / Cloudera / Google Big Query
  • Crazy stuff: Erlang的Mnesia, iOS的Core Data

数据抽象层

You should, 在大多数情况下, 不要向您选择使用的任何数据库编写原始查询. 更有可能, 在数据库和应用程序代码之间存在一个库, separating the concerns of managing concurrent database sessions and details of the schema from your main code. At the very least, 永远不要在应用程序代码中使用原始查询或内联SQL. Rather, 将其包装在一个函数中,并将所有函数集中在一个文件中,该文件的名称非常明显(例如.g., “queries.py”). A line like Users = load_users() ,就比……容易读得多 users = db.查询用户username, foo, bar, LIMIT 10 ORDER BY ID. 这种类型的集中化也使得在查询中保持一致的样式更加容易, 并限制在模式更改时更改查询的位置数量.

考虑利用的其他公共库和工具

  • 排队或Pub/Sub服务. 选择您的AMQP提供商,ZeroMQ, RabbitMQ, Amazon SQS
  • Storage. 亚马逊S3,谷歌云存储
  • Monitoring: Graphite/Hosted Graphite, AWS Cloud Watch, New Relic
  • 日志收集/聚合. Loggly, Splunk

Auto Scaling

  • Auto Scaling. Heroku, AWS Beanstalk, AppEngine, AWS Opsworks Digital Ocean

戒律5:不要越过小溪!

编程设计有很多好的模型, pub/sub, actors, MVC etc. 选择你最喜欢的,并坚持下去. Different kinds of logic dealing with different kinds of data should be physically isolated in the codebase (again, 这种关注点分离概念和减少未来读者的认知负荷). The code which updates your UI should be physically distinct from the code that calculates what goes into the UI, for example.

第六条:如果可能的话,让电脑来做

如果编译器可以捕获代码中的逻辑错误并防止任何不良行为, bugs, or outright crashes, 我们绝对应该好好利用这一点. 当然,有些语言的编译器比其他语言更容易做到这一点. 例如,Haskell就有着出了名的严格 compiler 这导致程序员花费大部分精力来编译代码. 一旦编译完成,“它就可以工作了”. For those of you who’ve either never written in a strongly typed functional language this may seem ridiculous or impossible, but don’t take my word for it. Seriously, 点击其中一些链接, 完全有可能生活在一个没有运行时错误的世界中. 这真的很神奇.

Admittedly, 并不是每种语言都有适合自己的编译器或语法(或者在某些情况下没有)!)编译时检查. 对于那些不知道的人, take a few minutes to research what optional strictness checks you can enable in your project and evaluate if they make sense for you. A short, non-comprehensive list of some common ones I’ve used lately for languages with lenient runtimes include:

Conclusion

这绝不是一个详尽的或完美的诫命清单,以产生“好”.e.(易于维护)的代码. That said, 如果我将来不得不选择的每个代码库都遵循这个列表中的一半概念, I will have many fewer gray hairs and might even be able to add an extra five years on the end of my life. 我肯定会发现工作更愉快,压力更小.http://en.wikipedia.org/wiki/CAP_theorem

聘请Toptal这方面的专家.
Hire Now
Zachary Goldberg

Zachary Goldberg

Verified Expert in Engineering

洛杉矶,美国

2016年4月20日成为会员

About the author

曾任谷歌工程主管和腾讯常驻企业家, 扎卡里是一位经验丰富的专业人士,拥有高管级别的经验.

authors are vetted experts in their fields and write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Expertise

PREVIOUSLY AT

Google

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

Toptal Developers

Join the Toptal® community.