构建持续交付

by Simon Schwartz

西蒙·施瓦茨(Simon Schwartz)

如何使交付成为您的重点将如何帮助您构建高质量的应用程序 (How making delivery your focus will help you build quality applications)

I was recently asked by our company’s executive team why our team was able to develop improvements to our product so quickly. This blog outlines some key guidelines, from a technical point of view, that our team followed to x iterate our product at speed safely. I tried my darndest to stay high level in this post while still providing technical details. The techniques we talk about aren’t things that we invented.

公司执行团队最近问我为什么我们的团队能够如此Swift地开发出对我们产品的改进。 该博客从技术角度概述了一些关键准则,我们的团队遵循这些准则来安全快速地迭代我们的产品。 我尽我最大的努力使这篇文章保持高水平,同时仍然提供技术细节。 我们谈论的技术不是我们发明的东西。

My fellow tech comrades on the team and I saw it as our role to reduce the friction to delivering value to our users. We also aimed to maintain a high quality of the applications we were responsible for. We did a large part of this by removing, simplifying, and automating the processes around delivering updates to our production codebase.

我的团队中的技术同志,我将其视为减少为用户提供价值的摩擦的角色。 我们还旨在保持我们负责的应用程序的高质量。 我们通过删除,简化和自动化将更新交付到生产代码库的过程来完成了大部分工作。

Keep in mind there are some projects that may have inherent complexity. Some of the techniques our team used may not fit your project. From my experience, working with legacy software can make it hard or impossible to simplify certain processes truly.

请记住,有些项目可能具有固有的复杂性。 我们的团队使用的某些技术可能不适合您的项目。 根据我的经验,使用旧版软件可能很难或不可能真正简化某些流程。

使交付成为重点 (Make delivery the focus)

Our team prioritized delivering frequent improvements to the production codebase above everything else. Well almost — we put things like mental health, letting people take a day off if they were sick, and being nice ahead of delivery.

我们的团队优先考虑对生产代码库进行频繁的改进,而不是其他所有方面。 好吧,几乎-我们采取了心理健康之类的措施,让人们在生病的时候可以放假一天,并在分娩前保持良好状态。

Code in production is the goal. We made sure that all ideas, designs and feature requests had a clear path for how we were going to get it to production. One technique we used to re-enforce this was only to show working code in showcases. We banned powerpoints and design mockups. We also found this made our showcases more engaging and interesting.

生产中的代码是目标。 我们确保所有想法,设计和功能要求都有一条明确的路线,说明我们如何将其投入生产。 我们用来加强此功能的一种技术只是在展示柜中显示工作代码。 我们禁止使用Powerpoint和设计模型。 我们还发现这使我们的展示柜更具吸引力和趣味性。

Meetings are optional. We found that this encouraged people who called meetings to articulate the purpose and value of the meeting clearly. It was up to team members to decide if they should attend a meeting. We wanted to prevent developers from being unnecessarily interrupted. It can take upwards of 30 minutes for someone to return to a productive state after being interrupted.

会议是可选的。 我们发现,这鼓励召集会议的人清楚地阐明会议的目的和价值。 由团队成员决定是否应参加会议。 我们希望防止开发人员受到不必要的干扰。 某人被打扰后可能要花费30分钟以上的时间才能恢复到生产状态。

Spend time solving user problems, not technology problems. We wanted to avoid spending countless hours discussing what technology to use or building our own technology. We used AWS Lambda so we didn’t have to think about servers and scaling. We used Create React App so we didn’t have to worry about build configuration for our front end app. We made early tech decisions and stuck to them.

花时间解决用户问题,而不是技术问题。 我们希望避免花费无数时间讨论要使用的技术或构建自己的技术。 我们使用了AWS Lambda,因此我们不必考虑服务器和扩展。 我们使用了Create React App,因此我们不必担心前端应用程序的构建配置。 我们做出了早期的技术决策并坚持了下来。

我们试图避免。 (? What we tried to avoid.)

  • We avoided spending weeks building our own tooling or frameworks when we could re-use them from elsewhere.当我们可以从其他地方重用它们时,我们避免花费数周时间来构建自己的工具或框架。
  • We avoided adding unnecessarily complex processes or ceremonies to the team. This included convoluted kanban boards or agile processes that weren’t benefiting us.我们避免向团队添加不必要的复杂流程或仪式。 其中包括混乱的看板或敏捷流程,这些都没有使我们受益。
  • We avoided spending weeks designing, building and supporting features that had no proof they would be useful to our users. Our design team did a great job of designing features based on user feedback and analytics.

    我们避免花费数周的时间来设计,构建和支持功能,而这些功能并没有证明它们对我们的用户有用。 我们的设计团队在基于用户反馈和分析的功能设计方面做得非常出色。

使部署成为非事件 (Make deployments a non-event)

Having a rapid release cycle meant we could get new features out to our users as soon as they were ready. We also recovered from bugs and outages much quicker. A major challenge of high-frequency deployments is moving at pace without introducing bugs. Automating this process is critical as it vastly reduces the time and effort it takes to deploy updates.

快速的发布周期意味着我们可以在用户准备就绪后立即向他们推出新功能。 我们还可以更快地从错误和中断中恢复。 高频部署的主要挑战是在不引入错误的情况下按步伐移动。 自动化此过程至关重要,因为它可以大大减少部署更新所需的时间和精力。

Automate the deployment. Rapid delivery requires the deployment process to be as frictionless as possible. Luckily nowadays we have many tools that can automate the entire deployment process. I recommend tools such as CircleCI and TravisCI. Our setup was when the new code was added to the release branch, the code was automatically deployed by our deployment tool.

自动化部署。 快速交付要求部署过程尽可能无摩擦。 幸运的是,如今,我们有许多工具可以自动化整个部署过程。 我建议使用CircleCI和TravisCI之类的工具。 我们的设置是在将新代码添加到release分支后,该代码由我们的部署工具自动部署。

Write (and automate) tests. When deploying code changes automatically, it is critical to understand the impacts the changes will have and to stop deployments that introduce bugs or regressions. This means we needed to write tests that confirm the code is functioning as expected.

编写(和自动化)测试 。 当自动部署代码更改时,至关重要的是了解更改将产生的影响并停止部署会引入错误或回归的部署。 这意味着我们需要编写测试以确认代码是否按预期运行。

Whenever we integrate new code to a release branch, the CI tool automatically runs our test suite. Any failures in the test suite will cancel the deployment process. Developers would also run this test suite locally to confirm everything worked before pushing changes. Automated testing is also much quicker, less cumbersome and less prone to human error than manual testing.

每当我们将新代码集成到发布分支时,CI工具都会自动运行我们的测试套件。 测试套件中的任何失败都将取消部署过程。 开发人员还将在本地运行该测试套件,以在推动更改之前确认一切正常。 与手动测试相比,自动测试还更快,更麻烦并且更不容易出现人为错误。

Delivering at speed doesn’t work if all new code needs to be manually tested by a human for an hour. As a team, we agreed that we would write tests for all the code we wrote. For cases where it wasn’t practical to write tests, we would need to give a reason. Any time we fixed a bug, we would also write a test that covered the bug. We made sure that we had tests for common user interactions and journeys (integration tests). As well as tests for the individual functions that made up our applications(unit tests).

如果所有新代码都需要人工人工测试一个小时,则无法快速交付。 作为一个团队,我们同意为所有编写的代码编写测试。 对于编写测试不切实际的情况,我们需要给出一个理由。 每当我们修复错误时,我们还将编写覆盖该错误的测试。 我们确保已针对常见的用户交互和旅程进行了测试(集成测试)。 以及组成我们应用程序的各个功能的测试(单元测试)。

Small frequent updates. Updating our codebase in small increments increased the rate we delivered improvements to our users. Small updates are easier to integrate into the codebase. Our code review process became more rigorous. It was easier and quicker for developers to review small pull requests. It is much easier to identify issues and impacts of new code because the surface area of the code was so small.

少量频繁更新。 以较小的增量更新代码库可以提高我们为用户提供的改进速度。 较小的更新更易于集成到代码库中。 我们的代码审查过程变得更加严格。 对于开发人员而言,审查小型拉取请求更容易,更快捷。 由于代码的表面积很小,因此识别新代码的问题和影响要容易得多。

One technique we found useful was moving the design quality assurance(QA) audit process to the pull request level. This made the QA process more focused and quicker as opposed to when it carried out every few days on a large set of multiple changes. As a team, we made an agreement that we would keep PRs small.

我们发现一种有用的技术是将设计质量保证(QA)审核过程移至拉动请求级别。 与每隔几天对大量更改进行一次质量检查相比,这使质量检查过程更加集中,更快。 作为一个团队,我们达成了一项协议,我们将使PR保持较小。

We also agreed that we would review PRs within half a day. If we weren’t able to review within that time frame, we needed to let the author know.

我们还同意,我们将在半天之内审查PR。 如果我们无法在该时间范围内进行审核,则需要告知作者。

我们试图避免。 (? What we tried to avoid.)

  • We avoided manually doing tasks that we could otherwise automate.我们避免了手动执行本来可以自动化的任务。
  • We avoided risks associated with deploying a large amount of code all at once. It’s not uncommon to deploy code that has bugs that are not picked up or bugs that only surface when the code runs at scale. The larger the surface area of our deployments, the larger the impact these issues will have.我们避免了一次全部部署大量代码带来的风险。 部署具有未被发现的错误或仅在代码大规模运行时才浮出水面的错误的情况并不少见。 我们的部署的表面积越大,这些问题将产生的影响越大。

使更改代码简单安全 (Make changing code simple and safe)

“To me, there is only one definition of well designed code. Well designed code is code that is easy to change” — Dave Thomas

“对我来说,只有一个定义良好的代码定义。 设计良好的代码就是易于更改的代码” – Dave Thomas

Having the ability to deploy code changes on demand is pointless if changing the code is hard and time-consuming. Writing code that is easy to understand and update helps us iterate at speed. As a technical team, we kept each other accountable through our code review process to ensure we were writing code as clearly and simply as possible.

如果更改代码既困难又耗时,则能够按需部署代码更改就毫无意义。 编写易于理解和更新的代码有助于我们快速迭代。 作为技术团队,我们在代码审查过程中互相追究责任,以确保我们尽可能清楚,简单地编写代码。

Write modular and reusable code. Functions are the building blocks of our applications. These functions should be small, decoupled and have a single purpose. This makes it easier for developers to follow and understand the logic of the application. It’s easier to repurpose existing functions to reduce the amount of code written. Changing functions is much safer because the surface area of function is so small. The effects of the change are easier to understand. As a team, we would carefully review each others pull requests and give feedback to help each other write the best code we could.

编写模块化和可重用的代码。 功能是我们应用程序的基础。 这些功能应小巧,分离,并具有单一目的。 这使开发人员更容易遵循和理解应用程序的逻辑。 重新利用现有功能以减少编写的代码量更加容易。 更改功能要安全得多,因为功能的表面积很小。 更改的影响更容易理解。 作为一个团队,我们将仔细检查彼此的拉取请求并提供反馈,以帮助彼此编写尽可能好的代码。

Write code for humans. There are two primary users of the code we write: computers who run the code and humans who read and change the code. Most developers are pretty good at writing code for computers. If your code runs or complies without bugs — it means you did a good job writing code for the computer. Some developers forget about writing code for humans. If the code is hard to understand it will take longer for developers to understand and update the code. We focused on making it clear the purpose, outputs, and inputs of each function.

为人类编写代码。 我们编写代码的两个主要用户:运行代码的计算机和阅读和更改代码的人员。 大多数开发人员都擅长为计算机编写代码。 如果您的代码运行或遵照执行,没有错误-这意味着您在编写计算机代码方面做得很好。 一些开发人员忘记了为人类编写代码。 如果代码难以理解,开发人员将需要更长的时间来理解和更新代码。 我们专注于明确每个功能的目的,输出和输入。

The inputs and outputs of functions were made clear with the type system. We used the inbuilt type system when using Go, and Flow when using JavaScript.

类型系统使功能的输入和输出变得清晰。 使用Go时使用内置类型系统,使用JavaScript时使用Flow。

We chose descriptive names for our variables. This made it clearer what data the variable held or what function is performed.

我们为变量选择了描述性名称。 这样可以使变量保存哪些数据或执行什么功能变得更加清晰。

// Both these functions do the same thing
function a(arr) {  return arr.filter(it => it.age < 30)}
function getUsersUnder30(userList) {  return userList.filter(user => user.age < 30)}

Write testable code. Whenever we change the code we need to be sure our changes have not regressed the previous functionality of the code. This is one of the great benefits of having tests. It adds a level of safety to making code changes. We made our lives easier by writing code in a way that made it simple to write tests for. A technique for writing code that is easy to test, is to use pure functions.

编写可测试的代码。 每当我们更改代码时,都需要确保所做的更改未使代码的先前功能退步。 这是进行测试的巨大好处之一。 它为更改代码增加了一定的安全性。 通过以简化编写测试的方式编写代码,使生活变得更轻松。 编写易于测试的代码的技术是使用纯函数

A pure function is a function that given the same inputs, will always return the same outputs. These functions are super simple to test. If you are interested in learning more about pure functions Eric Elliot has a fantastic article describing pure functions.

纯函数是给定相同输入的函数,将始终返回相同的输出。 这些功能非常易于测试。 如果您有兴趣了解有关纯函数的更多信息,那么Eric Elliot有一篇很棒的文章描述了纯函数 。

Unfortunately, you cannot write a function as a pure function if it has side effects. A side effect is something that operates outside of the scope of its function. This could be operations such as writing a file or sending an API request. Side effects can be tricky to test at the unit level, so these were separated from our pure functions.

不幸的是,如果函数具有副作用 ,则不能将其编写为纯函数。 副作用是超出其功能范围的事情。 这可能是诸如写入文件或发送API请求之类的操作。 在单位级别测试副作用可能很棘手,因此将这些副作用与我们的纯函数分开了。

我们试图避免。 (? What we tried to avoid.)

  • We avoided wasting time manually testing scenarios that we could automate.我们避免了浪费时间手动测试可以自动化的方案。
  • We avoided compromising code quality for speed. Compromising code quality for speed is redundant. Not only are you more likely to introduce bugs, but you are also creating a codebase that will eventually be very hard to change and debug. This will significantly slow down your ability to deliver new features and bug fixes.我们避免为了速度而牺牲代码质量。 为了速度而牺牲代码质量是多余的。 您不仅更有可能引入错误,而且还创建了最终将很难更改和调试的代码库。 这将大大减慢您交付新功能和错误修复的能力。

Thanks for reading!

谢谢阅读!

翻译自: https://www.freecodecamp.org/news/making-delivery-the-focus-techniques-for-delivering-quality-applications-222b79d301d9/

构建持续交付

构建持续交付_如何使交付成为您的重点将如何帮助您构建高质量的应用程序相关推荐

  1. 英文期刊催稿信模板_手把手教你写投稿信,另附查尔斯沃思高质量模板

    导语 本文是查尔斯沃思作者服务关于学术论文写作系列文章的最后一篇,我们邀请英国编辑团队资深成员,根据其自身丰富的撰稿经验,为中国作者呈现系统全面的写作指导建议,我们将其翻译成中文,方便大家理解.希望本 ...

  2. 敏捷交付_确保敏捷交付

    敏捷交付 Assurance and Agile - two words not commonly seen together, and for good reason. The early and ...

  3. 高并发内存占用持续下降_师兄,为什么删除数据后,Redis内存占用依然很高?...

    前言 上周刚来了个应届小师弟,组长说让我带着,周二问了我这样一个问题:师兄啊,我用top命令看了下服务器的内存占用情况,发现Redis内存占用严重,于是我就删除了大部分不用的keys,为什么内存占用还 ...

  4. 六轴机器人 宝元系统_庆云大国重器上线六轴智能焊接机器人,锻造高质量发展硬核...

    在大国重器坚持创新发展道路上,不断"借智"发展,提升科研保障能力,追求国际先进水平,为企业发展提供强劲动能. 六轴智能焊接机器人 六轴智能焊接机器人是大国重器自动化设备股份有限公司 ...

  5. android小程序案例_小程序案例赏析:高质量的小程序怎么做

    很多新手想做小程序,但却不知道好的小程序应该做成什么样子.下面就跟大家分享几个做得比较好的微信小程序案例,你可以从这些案例中学习一下,然后再做自己的小程序. 1.商城小程序案例 商城小程序如今是比较常 ...

  6. GitLab 与 Jenkins 结合构建持续集成环境

    持续集成概述及运行流程 CI/CD介绍 把开发工作流程分为以下几个阶段: 编码 → 构建 → 集成 → 测试 → 交付 → 部署 正如你在上图中看到,持续集成(Continuous Integrati ...

  7. 想高质量交付,需要先回答这三个问题

    我们一直都知道,高质量交付从来都不是一件轻松容易的事情,所以当每开启一个项目的时候,有三个问题要问自己: 1.项目的验收标准是否确立并得到共识? 不成熟的委托方会希望验收标准是模糊的,大致上会有两种原 ...

  8. 构建高质量的持续交付体系

    这是软件工程系列知识总结的第七篇文章,也是最后一篇. 前面的文章,聊了软件工程的基础理论.项目管理.需求分析.架构设计.软件测试以及线上服务的质量保障.其中在架构设计和线上服务的质量保障中,我也提到了 ...

  9. 京东金融移动APP高质量持续交付

    点击「京东金融技术说」可快速关注 1 前言 随着京东金融业务的不断拓展,客户端开发团队人数激增,代码量急剧膨胀,业务的成长和人员的倍增给技术架构.团队合作.产品的交付都带来了巨大的挑战,本文将讲述京东 ...

最新文章

  1. slf4j 日志监控
  2. 详解linux系列之sendmail邮箱服务的安装及配置
  3. Bootstrap的全局css样式部分
  4. 连州技工学校学计算机要交多少学费,技校学费一年大约需要多少
  5. c语言实验11答案,c语言实验9-11参考答案
  6. 机器视觉-halcon学习笔记1
  7. Java 7:满足Fork / Join框架
  8. 22桥接模式(Bridge Pattern)
  9. ORA-01841: (完整) 年份值必须介于 -4713 和 +9999 之间, 且不为 0情况解决
  10. mysql分表方法实现
  11. git 别名_Git别名简介:使用Git的更快方法
  12. Kubernetes资源分配(limit/request)
  13. 【SSH框架】之Spring系列(一)
  14. Spring Boot 初步小结
  15. everything 全盘文件查找工具及正则表达式的使用
  16. 软件观念革命:交互设计精髓_最全交互设计书单
  17. linux获取笔记本摄像头视频,Linux下利用Opencv打开笔记本摄像头问题
  18. C++ 泛型编程 map(统计人数)
  19. Android中Callable、Future、FutureTask的概念以及几种线程池的使用
  20. html批量转换xls格式,htm格式怎么转换excel

热门文章

  1. lseek函数的使用
  2. 我凭什么拿到了阿里、腾讯、今日头条3家大厂offer?通用流行框架大全
  3. 个人学习进度(第十六周)
  4. 红外感应模块+蜂鸣器实现简易报警(转)
  5. CentOS5.6环境安装oracle 10g(完整版)
  6. 扩展 CommandField 类别 - Header 加入新增钮
  7. 阿里巴巴分布式事务利器Seata环境准备
  8. MySQL 亿级数据需求的优化思路(二),100亿数据,1万字段属性的秒级检索
  9. 阿里一年,聊聊我成长了什么,入职阿里的职业生涯感悟
  10. MongoDB第二天