软件工程笔记-翻译

Photo by NESA by Makers on Unsplash

前言:

整体浏览收藏夹的发现了这篇来自Google的François Chollet关于软件工程的一些心得,读完感觉甚是戳中当下开发和管理过程中的很多痛处,翻译一下,仅供参考。

原文链接[需破窗]:

https://medium.com/s/story/notes-to-myself-on-software-engineering-c890f16f4e4d

开发阶段

  1. 代码并不仅仅是可以执行。代码也是一种跨团队沟通的方式,一种给别人描述如何解决问题的方式。方便阅读的代码不算是好,因为它本身就是编写代码最基础的部分,它涉及到清晰的代码结构、见名知义的变量名、对于复杂代码逻辑的插入注释。
  2. 不要问你拉代码之后为了你的下一次晋升,而是要问你拉代码之后为你的用户和社区做什么。避免所有的时间浪费在“台面的事情”上。如果不能清楚地对你的产品带来帮忙的话,宁可不要做这些功能。
  3. 代码也是有品味的。品味是通过对简单的追求逐步达到刻意约束的过程(对简单的极致追求)。要保持对简单的偏执。
  4. 请说不。因为当有人要求做某一个功能的时候并不意味着你要开发它。每一个功能的开发都是要超出它的初始成本:后期维护成本、文档编写成本、用户的学习成本。当我们问是否真的要这么做时,大部分情况下得到的答案是:不。
  5. 当你对一个新功能的开发请求说YES的时候,显而易见的是接收它通常不是最优选择。用户只会关注他们自己的功能使用,而你必须要有全局视角和对项目的全盘考虑。所以正确的答案是扩展已经存在的功能。
  6. 在持续集成上做投资,目标是做到全用例覆盖,确保你的一个可信代码的环境下开发,如果没有达到这一点,开始投入构建可使用的基础设施上来。
  7. 不必提前计划好每件事。先去尝试看看结果如何。尽早纠正错误的选择。确保你创造的环境是有可能性。
  8. 好的软件让困难的事情变得容易,仅仅是因为这个问题在开始的时候看起来困难,但并不意味着它的解决方案是复杂的或者难以使用。工程师们通常会在一个简单的地方机械性地给出不可预知的复杂解决方案,比如使用机器学习、构建一个APP、增加区块链等等。虽然有时不太明显,但是完全是有替代方案的。在你编写任何代码之前,确保你选择的解决方案不能再简单了。每一次的选择都要遵循第一性原则。
  9. 避免隐性逻辑。你发现你开发的隐性逻辑应当是明确的、可与他人分享的、可以自动化的。无论何时你如果想出了一个可重现的、算法化的流程,一定要将它记录在文档中,以便于其他团队成员能从这个流程中受益。除此之外,你应该在软件领域寻找一切可以自动化的流程并尽其可能的自动化(比如正确性检查)。
  10. 你做出的选择的整体影响应该被记入到整个设计过程中,而不只是你关注的那一点,比如收入或者增长。除了你关注的指标之外,你的软件对它的用户乃至整个世界有什么影响?是否有超过价值目标的负面影响?在保持你的软件可用性的同时你又可以做些什么来解决这些问题?
有人情的设计是将你的价值观融入你的创意。

API设计

  1. 你的API是有用户,所以它是有用户体验的。你做的每一个决定时请随时想着你的用户。对你的用户抱有同情心,无论他是初学者还是经验丰富的开发者。
  2. 在你的API文档中应当寻求最小化的影响你的用户。自动化那些可能自动化的东西,最小化用户需要的些动作和选择,不要暴露不重要的选项,设计的简单和一致的工作流反映了简单且一致的思考模型。
  3. 简单的事情应该是简单的,复杂的事情应该尽可能的简单。不要为了小众的需求增加大部分用户需求的学习成本。
  4. 如果一个工作流程的学习成本足够低,通过一两次的使用就能记住它应该是可能的。
  5. 你的API应该试图匹配当前领域专家或者从业者的认知水平。大部分人有领域经验但对你的API没有经验,他们应该通过最短的文档来直截了当地读懂你的API,虽然他们大部分情况是看几行示例代码、 看看有哪些对象是可以用的或者他们的函数方法有哪些。
  6. 参数的含义应该在不关心底层实现的情况下是可以看懂的。必须由用户定义的参数必须与用户要解决问题的模型相关,与你的代码实现无关。API描述的是关于它所解决问题,而不是背后的软件如何工作。
  7. The most powerful mental models are modular and hierarchical: simple at a high level, yet precise as you need to go into details. In the same way, a good API is modular and hierarchical: easy to approach, yet expressive. There is a balance to strike between having complex signatures on fewer objects, and having more objects with simpler signatures. A good API has a reasonable number of objects, with reasonably simple signatures.
  8. Your API is inevitably a reflection of your implementation choices, in particular your choice of data structures. To achieve an intuitive API, you must choose data structures that naturally fit the domain at hand — that match the mental models of domain experts.
  9. Deliberately design end-to-end workflows, not a set of atomic features. Most developers approach API design by asking: What capabilities should be available? Let’s have configuration options for them. Instead, ask: What are the use cases for this tool? For each use case, what is the optimal sequence of user actions? What’s the easiest API that could support this workflow? Atomic options in your API should answer a clear need that arises in a high-level workflow — they should not be added “because someone might need it.”
  10. Error messages, and in general any feedback provided to a user in the course of interacting with your API, is part of the API. Interactivity and feedback are integral to the user experience. Design your API’s error messages deliberately.
  11. Because code is communication, naming matters — whether naming a project or a variable. Names reflect how you think about a problem. Avoid overly generic names (x, variable, parameter), avoid OverlyLongAndSpecificNamingPatterns, avoid terms that can create unnecessary friction (master, slave), and make sure you are consistent in your naming choices. Naming consistency means both internal naming consistency (don’t call “dim” what is called “axis” in other places) and consistency with established conventions for the problem domain. Before settling on a name, make sure to look up existing names used by domain experts (or other APIs).
  12. Documentation is central to the user experience of your API. It is not an add-on. Invest in high-quality documentation; you will see higher returns than investing in more features.
  13. Show, don’t tell: Your documentation should not talk about how the software works, it should show how to use it. Show code examples for end-to-end workflows; show code examples for each and every common use case and key feature of your API.
Productivity boils down to high-velocity decision-making and a bias for action.

软件职业

  1. Career progress is not how many people you manage, it is how much of an impact you make: the differential between a world with and without your work.
  2. Software development is teamwork; it is about relationships as much as it is about technical ability. Be a good teammate. As you go on your way, stay in touch with people.
  3. Technology is never neutral. If your work has any impact on the world, then this impact has a moral direction. The seemingly innocuous technical choices we make in software products modulate the terms of access to technology, its usage incentives, who will benefit, and who will suffer. Technical choices are also ethical choices. Thus, always be deliberate and explicit about the values you want your choices to support. Design for ethics. Bake your values into your creations. Never think, I’m just building the capability; that in itself is neutral. It is not because the way you build it determines how it will get used.
  4. Self-direction — agency over your work and your circumstances — is the key to life satisfaction. Make sure you grant sufficient self-direction to the people around you, and make sure your career choices result in greater agency for yourself.
  5. Build what the world needs — not just what you wish you had. Too often, technologists live rarefied lives and focus on products catering to their own specific needs. Seek opportunities to broaden your life experience, which will give you better visibility into what the world needs.
  6. When making any choice with long-term repercussions, place your values above short-term self-interest and passing emotions — such as greed or fear. Know what your values are, and let them guide you.
  7. When we find ourselves in a conflict, it’s a good idea to pause to acknowledge our shared values and our shared goals, and remind ourselves that we are, almost certainly, on the same side.
  8. Productivity boils down to high-velocity decision-making and a bias for action. This requires a) good intuition, which comes from experience, so as to make generally correct decisions given partial information, b) a keen awareness of when to move more carefully and wait for more information, because the cost of an incorrect decision would be greater than cost of the delay. The optimal velocity/quality decision-making tradeoff can vary greatly in different environments.
  9. Making decisions faster means you make more decisions over the course of your career, which will give you stronger intuition about the correctness of available options. Experience is key to productivity, and greater productivity will provide you with more experience: a virtuous cycle.
  10. In situations where you are aware that your intuition is lacking, adhere to abstract principles. Build up lists of tried-and-true principles throughout your career. Principles are formalized intuition that generalize to a broader range of situations than raw pattern recognition (which requires direct and extensive experience of similar situations).