This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
<audio id="audio" title="21 | 架构设计:普通程序员也能实现复杂系统?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/42/c0/42e5ca0e826d33760bee83fc82dfb2c0.mp3"></audio>
你好,我是宝玉,我们已经正式进入到“系统设计”这个主题模块,今天我们先来聊一聊“架构设计”。
早些年软件很简单的时候不需要需求分析和架构设计直接采用边写边改Code And Fix模型也能做出来。后来软件复杂了就对程序员要求特别高了所以早些年的软件开发都是个人英雄主义盛行。比如张小龙一个人完成了Foxmail求伯君完成WPS王江民写KV杀毒软件……
不过,那时候对于普通程序员来说,去写这样复杂的系统,也是可望而不可及的。再后来软件产品越发复杂后,靠高手的开发模式也不可行了。
软件需求越来越多,而高手又是稀缺资源,所以要解决的一个问题就是:让普通程序员也能参与其中,一起实现复杂系统,而不必依赖于很多精英。
## 为什么软件项目需要架构设计?
要想实现让普通程序员也能实现复杂的软件系统,我们先要看看什么样的是复杂的软件项目。复杂的软件项目,通常有两个特点:需求不确定和技术复杂。
<img src="https://static001.geekbang.org/resource/image/9e/c6/9e7f7a98e8909ac6646c19a3ac632fc6.jpg" alt="">
关于需求不确定,我在前面的文章已经讲了很多,我们主要来看看技术的复杂性。技术的复杂性,主要体现在四个方面。
**1. 需求让技术变复杂**
如果需求本身很复杂,那么对应的技术也会很复杂。比如说你做一个个人博客网站,和做一个淘宝这样的网站,技术复杂度是有天壤之别的。
要响应需求的变化,也会让技术变复杂。对于明确的需求,相对来说技术实现是容易的。但是,随着需求地不断变化,新的需求可能会破坏原有的代码架构,导致系统越来越臃肿复杂,维护也越来越难。
**2. 人员会让技术变复杂**
现在软件开发通常不是一个人,而是一个团队。团队成员水平不一样,擅长的技术方向也不一样,让这一群人有效地协作也是很大的考验,简单的技术问题也会变成复杂的技术问题。
**3. 技术本身也是复杂的**
现在软件项目中选择编程语言、框架、技术组件、数据库等技术或工具,还可能需要应用像微服务、大数据、人工智能技术,这些技术本身就是复杂的,普通人都需要通过一定的学习才能掌握。
**4. 要让软件稳定运行是复杂的**
软件在开发完成后,要发布运行,但运行时也充满了各种不确定性。比如说明星发布八卦可能会导致微博宕机;阿里云宕机导致很多基于阿里云的系统也跟着一起无法提供服务。
因为技术的这些复杂性,会导致软件开发变得很复杂,开发成本很高。而架构设计恰恰可以在这些方面很好地解决技术复杂的问题。
**首先,架构设计可以降低满足需求和需求变化的开发成本。**
对于复杂的需求,架构设计通过对系统抽象和分解,把复杂系统拆分成若干简单的子系统。就像淘宝这样复杂的网站,最终拆分成一个个小的微服务后,单个微服务开发的难度,其实和个人博客网站的难度已经差不太多了,普通程序员都可以完成,降低了人力成本。
对于需求的变化,已经有一些成熟的架构实践,比如说像[分层架构](http://baike.baidu.com/item/%E4%B8%89%E5%B1%82%E6%9E%B6%E6%9E%84)这样把UI界面和业务逻辑分离可以让UI上的改动不会影响业务逻辑的代码像Wordpress这样基于插件和定制化的设计可以满足绝大部分内容类网站的需求降低了时间成本。
**其次,架构设计可以帮助组织人员一起高效协作。**
通过对系统抽象,再拆分,可以把复杂的系统分拆。分拆后,开发人员可以各自独立完成功能模块,最后通过约定好的接口协议集成。
比如说前后端分拆后有的开发人员就负责前端UI相关的开发有的开发人员就负责后端服务的开发。根据团队规模还可以进一步细分比如说前端可以有的程序员负责iOS有的程序员负责网站这样最终各个开发小组规模都不大既能有效协作又能各自保证战斗力。
**再次,架构设计可以帮助组织好各种技术。**
架构设计可以用合适的编程语言和协议,把框架、技术组件、数据库等技术或者工具有效的组织起来,一起实现需求目标。
比如说经典的分层架构UI层通过选择合适的前端框架例如React/Vue实现复杂的界面逻辑服务层利用Web框架提供稳定的网络服务数据访问层通过数据库接口读写数据库数据库则负责记录数据结果。
**最后,架构设计可以保障服务稳定运行。**
现在有很多成熟的架构设计方案,可以保障服务的稳定运行。比如说分布式的架构,可以把高访问量分摊到不同的服务器,这样即使流量很大,分流到单台服务器的压力并不大;还有像[异地多活](http://yq.aliyun.com/articles/57715)这样的架构方案可以保证即使一个机房宕机,还可以继续提供服务。
其实,满足需求和需求变化、满足软件稳定运行是架构的目标,对人员和技术的组织是手段。架构设计,就是要控制这些技术不确定问题。
我们也可以说:架构设计,就是通过组织人员和技术,低成本满足需求以及需求的变化,保障软件稳定高效运行。
## 什么是架构设计?
你现在已经知道了架构设计的价值,那么究竟什么是架构设计呢?要说清楚这点,我们可以分别从目标和方法两个角度来看。
最开始我以为架构设计的目标是满足业务需求,保证软件能正常工作。后来发现这其实只是最基本的要求,因为很多糟糕的架构设计,也能满足业务需求,让系统正常运行。
比如说有人把一个小网站拆分成几十个微服务运行,也是一种架构设计,但是这样,无论是开发成本还是运行成本都很高。
所以架构设计的目标,是**用最小的人力成本来满足需求的开发和响应需求的变化,用最小的运行成本来保障软件的运行。**
架构设计,已经有很多成熟的方法。比如说:
- 使用微服务这样的架构,把复杂系统拆分成一系列小的服务,服务再拆成功能模块,让人员更好地分工协作;
- 通过前后端分离,让程序员更专注于某个知识领域,降低开发难度;
- 用分层设计来隔离业务逻辑,减少需求变更带来的影响。
这些架构设计的方法,其实都是基于工程领域分而治之的策略,本质上就是将系统分拆,将人员分拆。但是光拆还不够,拆完了还得能拼回来,所以你要清楚架构设计的“道”。
**架构设计的道,就是组织人员和技术把系统和团队拆分,并安排好切分后的排列关系,让拆分后的部分能通过约定好的协议相互通信,共同实现最终的结果。**
这很像乐高玩具将一个个小的模块通过接口拼接在一起搭成一个大的模型。只不过在程序中换成了其他形式的接口比如前后端通过REST这种协议交互内部组件之间通过方法调用在软件项目中人员从大的开发团队被分拆成小组后小组之间通过流程规范协作。
## 如何做好架构设计?
架构设计,总给人感觉技术很高深。所以很多新手一提到架构设计,就有些畏足不前,不知道该从什么地方下手。
架构设计要做好,确实不是一个容易的事,需要大量的经验积累。但业界已经有了很多成熟的架构设计模式,我们不需要闭门造车,可以在理解清楚业务需求后,找到相近的架构设计,然后基于成熟的架构设计方案,进行改造,变成适合自己业务需求的架构。
接下来我就以极客时间的服务端为例来简要说明一下如何做架构设计。假设现在你要设计第一版本极客时间服务端的架构只有专栏课程一个核心功能目标用户访问量是日PV上万峰值每秒10个左右访问对稳定性要求高。那么你该如何做呢
#### 第一步:分析需求
架构设计,最基本的就是要能满足业务需求,所以搞清楚需求是至关重要一步。而产品需求,只有功能的描述,界面的交互,还需要进一步进行抽象。
一个常用的分析方法就是分析用例,也就是了解主要用户角色和其使用的场景。
我们如果把极客时间的专栏课程功能画成用例图,大概如下所示:
<img src="https://static001.geekbang.org/resource/image/af/22/af6b79d303f126d9e2f547b1a604ef22.png" alt="">
从图上可以看出有四种角色编辑、专栏作者、未付费用户和付费用户。每个角色有其独特的功能有些角色之间还有通用的功能。还需要注意的一点是每个用户都可能会通过不同的设备终端来使用这些功能网站、安卓手机、iPhone手机。
#### 第二步:选择相似的成熟的架构设计方案
在了解清楚需求后,就可以从业界成熟的架构设计模式中选取一个或几个。当然,具体选择哪些架构设计模式,需要你根据平时的学习积累来做判断。到这个阶段,同时还要考虑使用的语言和框架。
极客时间服务端主要包含两部分内容一个是给手机客户端提供的API服务还有就是网站需要的Web服务。第一个版本其实访问量并不大我们完全可以把API服务和网站服务合并成一个服务。另外专栏的内容文字内容涉及数据库的存储同时音频涉及文件存储。
这其实是一个典型的网站架构,可以基于传统的分层架构来实现。分层架构按照水平方向将系统拆分成几个层,每层都有清晰的角色和分工,不需要关心其他层的细节。
[<img src="https://static001.geekbang.org/resource/image/eb/88/eb230b721a36aaed80afbfd7641abf88.png" alt="" title="图片来源:软件架构入门">](http://www.ruanyifeng.com/blog/2016/09/software-architecture.html)
在选择好架构方案后,还需要考虑选择什么语言和开发框架。这部分选择需要根据团队情况和项目情况来综合评定。
比如说团队以PHP程序员为主就没必要贸然选择Java作为开发语言如果以js程序员为主就可以考虑使用Nodejs。因为这样的选择能让团队不需要太多的学习成本。
#### 第三步:自顶向下层层细化
其实我们专栏从工程思维开始,到后面提到的写文档、原型设计,都是建议能从整体到局部,这样更具有大局观,不容易过早陷入技术细节中。架构设计也是如此,好的实践是自顶向下层层细化。
在选择好成熟的架构设计方案后,可以基于方案,层层细化,逐步完善、调整和优化。
- 部署架构
这类分层架构网站,部署也比较简单。为了减少运维成本,我们可以基于云服务设计部署架构,选购云数据库和文件存储,选购虚拟机作为网站服务器。
那么部署架构可以比较简单,如下图所示:
<img src="https://static001.geekbang.org/resource/image/35/96/35e9e957e0b6a304704bb15ec2b00696.png" alt="">
基本上这个架构就可以基本满足运行需求。但要做到稳定性高还不够,万一数据库挂了或者网站服务器挂了,都可能会让服务中断一段时间。
所以我们可以增加一台异地网站服务器和一个异地云数据库实例作为备份,这样一旦网站宕机或者数据库有问题,可以切换到备机,马上恢复访问。所以调整后架构如下:
<img src="https://static001.geekbang.org/resource/image/35/c0/35f3abd053654cd23896c7259d5258c0.png" alt="">
这样我们就很好的满足了对运行稳定性的要求。
- 分层和分模块
按照分层架构的思路,我们可以把系统分成四层。
**用户界面层**:用户界面,负责展现功能以及和用户交互。<br>
**服务层**API服务和Web网站服务。<br>
**业务逻辑层**:实现业务逻辑,比如说如何读取用户订阅的专栏列表。<br>
**数据访问层**:对数据库的访问。<br>
**数据存储**:用数据库保存数据,文件库保存音频文件。
分层分好后,还需要基于前面的用例图,把相同的功能抽象出来,设计成模块,比如说留言相关的都放到留言的模块,文稿相关的都放到文稿模块。
最终的设计图大概会是这个样子:
<img src="https://static001.geekbang.org/resource/image/41/d6/410b864fd8d6cc34cb20eef07e46acd6.png" alt="">
在分层和分模块之后,就可以很好的对人员进行分工,可以把具体工作细分到某一层的某个模块。
- API设计、数据库设计、模块的设计
在分层和分模块的设计完成后就可以对API进行设计对数据库进行表设计。这部分就不展开细讲了。
还有一些模块的设计,还可以让负责开发该模块的程序员参与一起设计,这样一方面让他提前熟悉设计,另一方面也可以让他锻炼设计能力,提高参与积极性。
#### 第四步:验证和优化架构设计方案
在技术方案完成后,还需要去验证方案是不是满足设计的目标,能否满足需求和未来需求的变化,能否保障软件有效地运行。
方案的验证是贯穿整个设计始终的,一个完整的架构设计方案,需要有多次的评审会议,充分收集各方面的反馈,反复修改后才能最终确定下来。
在第二、三步,可能会生成几个技术方案,这时候就需要做出一些技术上的决策。决策时,需要考虑清楚方案是否能低成本的完成软件需求的开发,同时能低成本的运行和维护该软件。还有你要考虑架构预期要满足多长时间的业务增长,比如说半年还是一年还是三年。
在架构设计确定后,就可以基于架构设计的结果大家一起分工协作了。架构设计并不是确定后就不修改了,在实际开发的过程中,还需要根据情况对架构进行优化和调整。
比如说实际运行的时候发现API访问量很大会拖慢网站访问速度那我们就可以考虑把API和网站分拆开来各自做成单独的服务避免相互干扰。
## 推荐学习材料
OReilly 出版过一本免费的《[Software Architecture Patterns](http://www.oreilly.com/programming/free/software-architecture-patterns.csp)》, 介绍了五种最常见的软件架构。阮一峰老师有在[软件架构入门](http://www.ruanyifeng.com/blog/2016/09/software-architecture.html)中对其各种模式进行介绍。
还有像《[架构师之路](http://www.w3cschool.cn/architectroad/)》这样的开源电子书,对于服务端架构中常用的设计,有很不错的总结。《[图解:从单个服务器扩展到百万用户的系统](http://mp.weixin.qq.com/s/wSCeO8QVYniMIGcBFDZyjw)》这篇文章对单服务器到大用户系统的演变也有通俗易懂的总结。《[以“前浪微博”场景为例,谈谈架构设计流程四步曲](http://www.infoq.cn/article/architecture-design-process)》这篇文章也介绍了一种非常好的架构设计方法。
最后,推荐一本书:《[架构整洁之道](http://book.douban.com/subject/30333919/)》。我觉得是架构设计书籍中写的最透彻最浅显易懂的一本。
## 总结
今天,我们一起学习了软件工程中一个非常重要的知识,那就是架构设计。
架构设计,是为了控制软件项目中技术复杂的问题。架构设计,通过组织人员和技术,低成本满足需求以及需求的变化,保障软件稳定高效运行。
架构设计可以通过四个基本步骤:
- 第一步:分析需求;
- 第二步:选择相似的成熟的架构设计方案;
- 第三步:自顶向下层层细化;
- 第四步:验证和优化架构设计方案。
通过良好的架构设计,可以有效降低开发难度和成本,让普通程序员也能实现复杂系统。
## 课后思考
请你思考一下,为什么淘宝这样的网站需要用微服务这样的架构,而一个个人博客网站不需要微服务?你认为极客时间这样的网站用的什么样的架构?也欢迎分享你觉得不错的架构书籍和文章。欢迎在留言区与我分享讨论。
感谢阅读如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,139 @@
<audio id="audio" title="22 | 如何为项目做好技术选型?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a6/3a/a6dd509f3c87dd8b199705771aca723a.mp3"></audio>
你好,我是宝玉,我今天分享的主题是:如何为项目做好技术选型?
在架构设计过程中,肯定绕不开技术选型这个话题,大到架构、框架、语言选择,小到用什么组件、设计模式。
这也是最容易引起争议的话题无论是现实中还是网上到处有各种语言、框架的争论Java好还是C#好前端框架是Vue好还是React好跨平台手机开发该选React Native还是Flutter……
虽然这种争论从来没什么结果,但当你做技术选型时,却很容易受到这些信息的干扰,尤其是你身边有几个某种语言或者框架的狂热粉丝的话,他们会不停地在你旁边吹风,说他喜欢的语言或框架的各种好处。
包括我们自己做技术选型时也会有很多个人偏好在里面。比如我以前对微软技术栈特别熟悉也特别喜欢做技术方案就会偏向微软技术栈我喜欢React做前端技术选型也会偏向React的方案。
通过上一篇架构设计的学习,我们知道,**架构设计的主要目标,是要能低成本地满足需求和需求变化,低成本地保障软件运行。**然而对技术的个人偏好,很可能让你在技术选型时,忽略架构设计的目标,导致满足需求的成本变高,或者运行成本居高不下。
所以今天,我们一起来探讨一下,在软件工程中,怎么样才能避免这种选型的倾向性,科学客观地做好技术选型。
## 技术选型就是项目决策
技术选型,就是在两个或者多个技术方案中选择适合当时项目情况的方案。**技术选型看起来是个技术的选择,但其实是一个和项目情况密切相关的项目决策。**
在项目中,除了技术上的选型,类似的选择也有很多,比如说产品设计中:某个功能该不该加?该选哪种动画效果?比如制定测试方案的时候,选择哪一种压力测试工具?选择哪个测试框架?这些选择,本质上就是一种项目决策。
要做好技术选型,就是要做好项目决策。那么怎样从做项目决策的角度来选择合适的技术选型呢?
#### 受制于时间、范围和成本的约束
我们在《[08 | 怎样平衡软件质量与时间成本范围的关系?](http://time.geekbang.org/column/article/85302)》中学习了项目金三角的理论,也就是项目受制于三个因素:时间、范围和成本。
技术决策作为一种项目决策,也要受制于时间、范围和成本,在决策时不能超出这三者的边界。
比如说在项目时间紧时,决策上就要偏向能提升开发速度的技术;在成本吃紧的情况下,要多用成熟的免费的框架、工具,避免用贵的商业软件或者自己造轮子提升成本;在范围大、需求多的情况下,架构就要考虑如何能简单快速完成需求。
还要注意一个问题就是随着项目的推进,其实制约项目的三个因素一直在动态变化,需要及时根据情况调整技术决策。
举个例子来说2004年飞信PC客户端做第一个版本的时候那时候主要的约束是成本只有一个C++程序员,这个程序员会用什么技术就用什么技术,谈不上选型。
到2005年做第二版本时有了几个人但是时间上要求快所以就选择了能提升开发速度的C# Winform技术方案。到2008年做第三版时人手充裕了也没有进度上的压力这时候主要就追求用户体验、性能所以又选择了C++的技术方案重新开发。
#### 要分析可行性和风险
我们在专栏前面的内容中学习了可行性研究和风险管理的知识。如果在项目决策时,不考虑可行性,不预估风险,就极有可能导致决策失败。
就像在《[09 | 为什么软件工程项目普遍不重视可行性分析](http://time.geekbang.org/column/article/85730)》那篇文章中的案例技术选型时没有考虑到License的法律问题导致项目失败。还有在《[14 | 风险管理不能盲目乐观凡事都应该有B计划](http://time.geekbang.org/column/article/87787)》那篇文章中的案例选择React时没有考虑到可能导致的风险导致项目延迟。
当然,换个角度说,如果在项目中,选择新技术的风险可以接受,也能满足时间、成本和范围的约束,还可以达到丰富团队技术栈的目的,那也是可以的。
#### 要考虑利益相关人
在做项目的决策时,如果决策时没有人代表利益相关的人,就可能会做出不考虑他们利益的决策。
选择适合的技术选型时也要考虑到这一点。比如说光顾着选用新酷的技术而没有考虑客户的利益导致成本增加进度延迟比如在选择UI组件时只想着哪个调用方便而不考虑产品经理的利益导致产品体验不好。
#### 项目决策中常见的坑
无论是技术选型也好,还是其他项目决策,经常会遇到一些坑,一不小心就会踩上去。
- 把听到的观点当事实
现在网上充斥着各种观点一个React的粉丝会给你描述React的各种优点而不会告诉你学习曲线有多陡峭一个不喜欢微软技术的程序员会把.Net贬低的一文不值一篇鼓吹Mongodb多好的文章可能是收了钱的软文。
每个人都有自己的观点没有问题,但是不能把观点当成事实,尤其是在做决策之前,至少需要验证一下。
- 先入为主,有了结论再找证据
在做技术选型或者项目决策时还有一个问题就是可能心中已经有了答案后面所谓的决策不过是寻找有利于自己答案的证据。比如说我特别喜欢React在做技术选型时就会拼命寻找对React有利的数据作为证据这其实可能会导致结论并不客观。
所以当你选择技术选型的时候,要像做项目决策一样思考分析。要想你的决策能正确,就要注意项目中范围、时间和成本的约束,要分析可行性和风险,要考虑利益相关人,最后还得要避开常见的一些坑。
## 如何做好技术选型?
现在我们知道了要像做项目决策一样,去选择适合自己项目的技术选型,那么具体该怎样做呢?
我们在《[02 | 工程思维:把每件事都当作一个项目来推进](http://time.geekbang.org/column/article/83277)》中学习了工程思维和工程方法,在《[12 | 流程和规范:红绿灯不是约束,而是用来提高效率](http://time.geekbang.org/column/article/87129)》中学习了流程规范。对于技术选型问题,我们一样也可以考虑借鉴工程方法设计一套流程,基于流程去做技术选型或项目决策,来保证整个过程能科学可行,充分考虑项目决策的特点,避开常见的坑。
对于技术选型包括项目决策类的问题,我们可以分成:问题定义、调研、验证、决策这几个阶段。
#### 问题定义
在问题定义阶段,需要搞清楚两个问题:为什么需要技术选型?技术选型的目标是什么?
以前看过一个技术漫画《[The problem is not the tool itself](http://www.commitstrip.com/en/2014/06/03/the-problem-is-not-the-tool-itself/)》。
“我想我们已经达到MySql的极限非常慢…我们得面对数据巨大的事实”“我们应该迁移到NoSQL我已经准备了一个3个月的战斗方案瞧瞧这”“框架重构、培训、内部工具升级”“等等让我检查一下”“你忘了建索引加上索引可以让速度提升20倍”“忘记索引你可真行。”
[<img src="https://static001.geekbang.org/resource/image/fe/f3/fe1f72418d928840b0412e25e734b3f3.png" alt="" title="图片来源Commitstrip">](http://www.commitstrip.com/en/2014/06/03/the-problem-is-not-the-tool-itself/)
这种事情在软件项目中可不少见,很多时候为了解决问题引入一个新技术,然而真的需要吗?也许我们可以基于现有技术方案进行优化,根本就不需要引入一个新的技术或新的框架。
还有一个就是技术选型的目标需要明确,你的技术选型目标是为了使用新酷技术呢?还是为了提升开发效率?还是为了降低开发成本?
**只有明确了技术选型的目标,才能有一个标准可以来评判该选择哪一个方案。**
就像上面例子中提到的第二版的飞信PC客户端目标就是要提升开发速度所以就选开发效率高的C#。
#### 调研
在明确技术选型的目标后,就可以去调研,看有哪些技术选型可以满足目标,包括开源的方案和商业的方案。
在调研时,可以参考前面“项目决策的特点”中的内容,从几个方面去分析:
- 满足技术选型目标吗?
- 满足范围、时间和成本的约束吗?
- 是不是可行?
- 有什么样的风险?风险是不是可控?
- 优缺点是什么?
在调研结束后可以筛选掉明显不合适的最终保留2-3种方案留待验证。必要的话可以一起讨论最终确认。
#### 验证
一个技术是不是合适,如果不够了解,没有应用过的话,实际用一下是很有必要的。可以通过一个小型的快速原型项目,用候选的技术方案快速做一个原型出来,做的过程中才能知道,你选择的技术选型是不是真的能满足技术选型的目标。
就像前面举的飞信PC客户端的例子在决定第二版本是否使用C#开发时,其实做了大量验证工作。当时.Net Framework还不普及要打包整个.Net Framework到安装包里面这体积就太大了这是一个很大的问题。
后来发现有一个产品叫Salamander它可以只打包程序所需要的dll库文件这样体积就可以控制在20mb以内最后在制作安装包时用7zip压缩就可以让安装包控制在10mb左右。在验证阶段证明了安装包体积是可以缩小的基于C#开发是可行的才最终选定了C#的技术方案
#### 决策
在调研和验证完成后,就可以召集所有利益相关人一起,就选择的方案有一个调研结果评审的会议,让大家提出自己的意见,做出最终的决策。
必须要承认,对于技术选型来说,是有不确定性的。即使通过上面的流程,也一样可能会做出错误的决策。但有一个科学的流程,至少可以保证提升做出正确决策的概率。
如果遇到很纠结的情况,就需要负责决策的人来拍板了,这时候其实并不一定有对错,重点的就是做出一个选择,然后按照选择去执行。有时候迟迟不选择、不拍板才是最坏的结果。
在项目结束后,也要对之前技术选型和项目决策做总结,不断的完善技术选型和项目决策的机制,帮助未来更好的进行决策。
## 总结
今天,我带你一起探讨了技术选型的问题。技术选型,本质上是项目决策的一种,也符合项目决策的一些特点。也就是说,技术选型的选择要受制于范围、时间和成本的约束,要分析可行性和风险,要考虑利益相关人。还有一些坑要小心避开,比如要避免把听到的观点当事实,要验证;要避免先入为主,不要有了结论再找证据。
要做好技术选项,要有一个科学的流程,首先要明确技术选型的目标,避免没必要的引入新技术;然后要充分调研;还要对备选的方案进行验证;最终和利益相关人一起决策。
技术选型,也不要太过于纠结,要勇于决策,选定了就坚定的去执行。
## 课后思考
你所在项目中是如何做技术选型的?有哪些不错的方法和原则?你在技术选型时,通常是选择保守的还是新酷的?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,147 @@
<audio id="audio" title="23 | 架构师:不想当架构师的程序员不是好程序员" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0a/ed/0ad8c098a1033e893aa1d1354baef4ed.mp3"></audio>
你好,我是宝玉,今天我想与你讨论一下要想成为架构师,你需要具备哪些能力。
很多程序员的梦想,就是将来能成为一名架构师。包括我刚学编程那时候,也是以当架构师为目标,觉得不想当架构师的程序员不是好程序员,希望将来能成为一个优秀的架构师。就像拿破仑那句名言:“不想当将军的士兵不是好士兵。”
随着工作经历的增多,我也开始参与到架构设计中。对架构设计了解的越多,我越发觉得,其实做架构设计,并不代表一定要有一个架构师的头衔。
拿破仑那句名言原句是“Every French soldier carries a marshals baton in his knapsack”意思是“每个士兵背包里都应该装有元帅的权杖”。
元帅的权杖,意味着大局观,元帅的思维方式。当士兵背包里装有元帅的权杖,就意味着士兵也能胸中有大局观,能有元帅的思维,理解元帅在特定战场上想什么,这样能更好的执行命令,提升整体的战斗力。
其实拿破仑的本意是激励每一名上战场的士兵都要有大局观,有元帅的思维,并不需要每一个人都一定去当将军、当元帅。
这也适用于技术领域,对于程序员来说,并不代表一定要有一个架构师的头衔,而是心中有大局观,有架构师的思维,从而能理解架构设计,能写出好的程序。
## 什么是架构师思维?
通过上一篇的学习,我们知道架构设计,是要控制技术的复杂性。对于架构师来说,要控制技术复杂性,有几种有效的方式:抽象、分治、复用和迭代。
架构师思维,其实就是这几种思维的集合。
#### 抽象思维
抽象思维可以说是整个架构设计的基础。因为对于架构设计来说是要为了满足业务需求的而业务需求都是一些文字性的描述、原型、UI设计图这些需求要最终变成代码让机器执行就必须先进行抽象抽象成计算机能识别的模型。
其实抽象思维我们不陌生因为我们从小学习的数学就有很多抽象思维的训练。举例来说我们小时候做的鸡兔同笼问题看起来很复杂但是如果我们会二元一次方程把鸡抽象成x兔子抽象成y就可以用二元一次方程列出相应的方程式从而求出解。
**在软件项目中,遇到类似的场景,就会考虑抽象出来,总结一个规则和方法。**有时候即使场景不同,也可以把其中有共性的内容抽象出来,可以更方便的使用。
举个例子,我们在之前文章中有对极客时间专栏做用例分析,其中有四个角色:编辑、作者、未订阅用户和订阅用户。其实这四种角色,都可以抽象成“用户”模型,然后通过对用户设置不同的角色属性,来应用成不同的角色。
还有像极客时间专栏的一篇文稿、视频课程的一节视频课,都有标题、内容、作者、留言等信息,所以可以抽象成“文章”模型,通过文章的类型、内容来区分专栏文稿还是视频课。
在架构设计中,对需求进行抽象建模后,可以帮助我们隐藏很多无关紧要的细节,我们在高层次的架构设计时,可以关注在几个主要的模型上,而不必关心模型内的细节实现。
#### 分治思维
架构设计的一个重点,就是要对复杂系统分而治之,分解成小的、简单的部分。但光分解还是不够的,同时还需要保证分解后的部分能够通过约定好的协议集成在一起。
分治思维在架构设计中有很多经典的应用。比如说上一篇介绍的分层架构把UI 部分与其业务逻辑部分隔离这样这两部分就既可以各自进行变更又互不影响。比如说UI交互修改不需要修改业务逻辑代码业务逻辑部分对性能进行优化不需要修改UI界面。而每层之间可以通过约定好的方法或者API进行交互。
还有像我们平时说的大数据,高并发这些复杂问题,也是通过分治来解决的。要知道单台机器,无论你性能如何优化,都是有其极限的。而像“双十一”这种高峰时刻,瞬间的流量可能是几百、几千万,就需要通过设计合理的策略,分化到不同的服务器,让每个服务器的流量不至于太大。参考:《[秒杀系统优化思路](http://www.w3cschool.cn/architectroad/architectroad-optimization-of-seckilling-system.html)》。
这种分治的思维其实不仅适用于架构上,也适用于平时程序员写代码。比如说有些程序员写代码,喜欢把大量的逻辑放在一个方法或者一个类里面,最后极其难以理解和维护,如果能分拆成几个小的方法或者小的类,不仅结构更清晰,也更容易理解和维护。
#### 复用思维
复用是一种非常简单有效的提升开发效率的方法,通过对相同内容的抽象,让其能复用于不同的场景。
举例来说,我们前面提到极客时间的专栏和视频课程,可以作为两个不同的模块进行开发,但是实际上内容差不多,如果能抽象成同一个“课程”模块,这样专栏和视频课程的模块就可以复用“课程”模块,不需要维护两份相似的代码,进而提升开发和代码维护的效率。后面如果要增加每日一课和微课,也不需要重新开发,只要复用之前的“课程”模块即可。
以前我在DePaul读书时要给学校做一个教学播放的软件由于当时技术框架选的是React而React没有合适的视频播放组件于是我只好自己实现了一个。实现完成之后我觉得这个视频播放功能肯定有很多人也需要如果能复用的话会很实用。于是我把它封装后放到GitHub上解决了很多人需要在React中播放视频的需求。到现在已经有超过1000个Star。
复用思维在日常写程序的时候也很常用,比如有的程序员喜欢复制粘贴代码,所以经常看到很多重复的代码,如果要修改,得修改好几个地方。如果能把这些重复的代码提取成公共的类或者方法,就可以减少很多重复,让代码更简洁和易于维护。
## 迭代思维
好的架构设计,通常不是一步到位,而是先满足好当前业务需求,然后随着业务的变化而逐步演进。
就像淘宝这样的业务,它背后的架构设计也不是一步到位成现在这样,拆分成好多微服务。最开始,它也只是个普通的分层架构,后来随着业务不断扩展,逐步迭代成今天这样复杂的架构。
这种迭代的思维,在写程序时也很重要。因为很多程序员喜欢追求完美,期望能一步到位,然而这样带来的问题是开发成本会大量增加,导致进度延误。另一方面,如果对需求的变化预测不正确,就会有很多冗余的代码,后面难以维护。
其实,开发人员对以上提到的这些思维模式都不陌生,只是在实践的时候,总是有意无意地忽略了。
## 好的架构师什么样?
对于程序员来说,培养架构师思维,并不是很难的事情。然而要成为好的架构师,光有架构师思维还不够。
**一个好的架构师,不仅技术要好,还要懂业务;能从整体设计架构,也能在局部实现功能。**
比如说一个做互联网软件架构设计有丰富经验的架构师,要去做建筑行业软件的架构设计,短时间内一定是很难设计出好的架构,因为他需要先熟悉建筑行业软件的业务,才能设计出符合业务特点的架构。
有一种架构师叫“PPT架构师”也就是说擅长写PPT画架构图。对各种热门的名词如数家珍。但是脱离一线开发对业务和底层基础知识知之甚少。这样的架构师设计出来的架构通常是不接地气的实现起来会非常困难成本也高。
因为作为架构师,如果不写代码,是不能体会出设计不好带来的问题,无法及时地对架构中的问题做出调整。
所以好的架构师,一定要是程序员出身,并且能坚持做一线程序员。也许他不需要写大量的业务代码,但至少要参与一部分编码工作,以及代码审查工作,以保证架构的正确执行。
好的架构师,不仅要有技术深度,还要有一定的技术广度。因为技术的选型,通常不能局限于一种技术,需要根据业务特点和团队特点灵活地选择。
好的架构师还有一个能力就是沟通能力。作为程序员,可能把自己的模块开发好就不错了,相对不需要太多的沟通工作。但是架构师就不一样,除了架构设计,还有大量沟通工作。
首先架构师要经常和产品经理打交道,反复确认需求,了解需求细节,只有这样才能分析清楚需求,了解各种用户场景。
然后架构师设计出来的架构,要通过文档、会议来讲给其他人听,能让其他人理解架构,用好架构。
所以要成为好的架构师,需要具备几个条件。
1. 有架构师思维:具备良好的抽象思维、分治思维、复用思维和迭代思维;
1. 懂业务需求:能很好地理解业务需求,能针对业务特点设计好的架构;
1. 有丰富的编码经验:像抽象、分治、复用这些能力,都需要大量的编码练习才能掌握;另外保持一定量的编码经验也有助于验证架构设计;
1. 良好的沟通能力:架构师需要沟通确认需求,需要让团队理解架构设计。
具备了这些条件,就可以成为很好的架构师,设计出好的架构,组织好人员和技术,低成本的满足好需求和需求变化,以及系统的运行。
<img src="https://static001.geekbang.org/resource/image/11/30/115f943a2e6377cc19197dabe75e6230.jpg" alt="">
## 如何成为好的架构师?
**想要成为好的架构师,没有什么捷径,需要比普通程序员更多的努力才行。**如果你有志向成为架构师的话,我的建议是:
- 要成为一个优秀的程序员
技术好是成为架构师的基础条件。需要让你的代码容易读,容易扩展,能重用。这样通过大量的编码实践,才能逐步地培养出好的架构师思维。
- 多模仿多学习
在刚开始的时候,不用想着闭门造车,想出一个特别牛的架构。反倒不如先把业界成熟的流行的架构吃透,用好。
现在网络上也有很多好的开源项目,这些开源项目都有良好的架构设计,可以找几个跟你研究方向相关的项目,本地搭建一下,然后自己试一下,最好能弄一个自己的项目二次开发或者模仿一遍,做中学,是最简单有效的。
我以前在用Asp.Net的时候就基于一个开源的Asp.Net项目Community Server做了大量的二次开发工作这对我后来做架构设计帮助非常大因为我从里面学习和实践了很多非常好的架构设计思想。
- 选择好行业和平台
软件其实下面细分了很多行业领域,大类有像互联网应用、企业应用、游戏应用,大类下面又有细分的小类。比如说企业应用又和各行各业的业务结合在一起的,像建筑行业软件,就需要有建筑行业的专业知识。
前面我说过,架构师要同时懂业务和技术,而这些行业知识,也不是短时间内能积累起来的。所以如果想当架构师,最好能选择一个合适的行业,能在一个行业里面早点积累足够的行业知识,后面做架构设计的时候,就能更好地设计出符合业务特点的架构。
同时,这些行业领域的业务经验,和技术结合的架构经验,也会成为你个人独特的优势,不容易被替代。
还有平台也很重要,好的平台,能给你更多的实践机会。所以你看极客时间上那些开课讲架构、微服务的,无一例外都是大厂出来的,因为只有大厂,才有机会去实践这种高并发大数据的架构设计。
如果你有志成为架构师,不能光埋头写程序,也要早做打算,选择适合你自己的行业和平台,少走弯路。
## 总结
今天,我们谈了“不想当架构师的程序员不是好程序员”这个话题。其实对于程序员来说,并不代表一定要有一个架构师的头衔,而是心中有大局观,有架构师的思维。从而能理解架构设计,能写出好的程序。
架构师思维,指的是要具备良好的抽象思维、分治思维、复用思维和迭代思维。
另外没有架构师的头衔,也一样可以做架构设计,只要你有架构师的能力就可以了。而好的架构师,需要具备:
- 有架构师思维;
- 懂业务需求;
- 有丰富的编码经验;
- 良好的沟通能力。
要想成为好的架构师,没有什么捷径可以走,首先需要要成为一个优秀的程序员,然后多模仿、多学习好的架构设计,最后还要早点选择好行业和平台,积累好行业的业务知识,借助平台获得大量的实践机会。
## 课后思考
互联网架构师和企业架构师有什么不同?你有没有成为架构师的梦想,有什么打算?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。

View File

@@ -0,0 +1,193 @@
<audio id="audio" title="24 | 技术债务:是继续修修补补凑合着用,还是推翻重来?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/3b/80/3b8c7941556cf8badc637c08527cb280.mp3"></audio>
你好,我是宝玉,今天我想与你讨论一下关于技术债务的问题。
做开发的同学对以下场景应该不会陌生:
- 为了赶项目进度,单元测试代码就来不及写了,打算以后再补;
- 随着需求的变化,原本的架构设计已经不能很好地满足新的需求,但是又不想对架构做改动,于是就绕开架构设计增加了很多代码;
- 一个旧的系统,没有文档没有注释,技术老旧,难以维护。
这些问题,如果没有及时修正,就会导致代码臃肿、系统效率低下,难以维护,也难以新增功能。
有一个很形象的名词叫“技术债务”,用来形容上面这些架构或代码上的质量问题。
所以今天的课程,我将带你一起来了解一下什么是技术债务,它形成的原因是什么,以及怎么来管理技术债务。
## 什么是技术债务?
我们在学项目管理金三角时,有一张表示软件质量与时间、成本、范围关系的三角形图,也特别解释了为什么质量要放在三角形中间,因为质量往往是其他三个因素平衡后结果的体现。
<img src="https://static001.geekbang.org/resource/image/7f/f7/7fa5c8351b4590a2bc8a482955c133f7.jpg" alt="">
范围不减,成本不增加,还想节约时间走捷径,就会影响到质量。这个“质量”,不只是产品质量,还有架构质量和代码质量。这种对质量的透支,就是一种债务。**而技术债务,就是软件项目中对架构质量和代码质量的透支。**
技术债务确实是个形象生动的比喻,让你意识到它是和成本挂钩的,而且技术债务也有金融债务的一些特点,比如有利息,再比如技术债务也有好的一面。
#### 技术债务是有利息的
债务的“利息”,就是在后面对软件做修改的时候,需要额外的时间成本。
假设我们做一个项目在刚开始时架构良好代码整洁添加一个功能可能需要4天时间。随着项目不断维护因为走捷径积累了一些技术债务这时候再开发一个同样复杂度的功能就需要5天时间了。
这多出来的1天就是技术债务造成的利息。因为你需要时间去梳理现在臃肿的代码以找到合适的位置添加代码修改代码后还可能导致原有系统不稳定需要额外的时间去修复系统不稳定的问题。
#### 技术债务不一定都是坏的
现实中,如果是贷款买辆豪车,一方面要支付利息,一方面车子一直在贬值,这不一定是个良性的债务;但如果你贷款买房子,虽然支付了利息,但如果房子升值,这个债务其实是良性的。
在软件项目中,也经常会刻意的欠一些技术债务,提升短期的开发速度,让软件能尽快推出,从而抢占市场;还有像快速原型开发模型,通过欠技术债务的方式快速开发快速验证,如果验证不可行,甚至这笔技术债务都不需要偿还了。
但技术借债也一样不能是无限制的,因为借债越多,利息越大,当收益抵不过利息时,就会陷入恶性循环,导致开发效率低下,进度难以保障。
所以对于项目中的债务,我们要清楚的知道有哪些技术债务,以及它给项目带来的收益和产生利息,这样才能帮助我们管理好这些债务。
## 技术债务产生的原因
如果现实中有人负债累累,那么多半有几个原因:这人对债务没有规划、生活所迫不得不借债、为了长远利益而临时借债、不知情的情况下欠了债务。
其实技术债务产生的原因也类似所以《重构》一书的作者Martin Fowler把技术债务产生的原因分成了两个维度
1. 轻率reckless还是谨慎prudent
1. 有意deliberate还是无意inadvertent
这两个维度正好可以划分成四个象限,如下图所示:<br>
[<img src="https://static001.geekbang.org/resource/image/9e/88/9ee240f45ed039399819232419bb3088.png" alt="" title="图片来源Technical Debt Quadrant">](http://martinfowler.com/bliki/TechnicalDebtQuadrant.html)
- **轻率/有意的债务**
这个象限,反映的是团队因为成本、时间的原因,故意走捷径没有设计、不遵守好的开发实践,对于债务没有后续的改进计划的情况。
例如不做设计直接编码,后期也没有打算重构代码。或者是团队成员以新手程序员为主,没有足够的资深程序员指导和审查代码。
这样产生的债务,短期可能还好,但是因为技术债务会一直积累,会导致利息越来越多,最终带来的负面效果会越来越大。
- **谨慎/有意的债务**
这个象限,则反映的是团队清楚知道技术债务的收益和后果,并且也制定了后续的计划去完善架构和提升代码质量的情况。
比如说为了尽快发布产品,先采用“快猛糙”的方式开发,后续再对代码进行重构。
这样产生的债务,因为能及时偿还,所以既可以短期有一定时间上的收益,长期也不会造成负面影响。
- **轻率/无意的债务**
这个象限,反映了团队不知道技术债务,也不知道要后续要偿还技术债务的情况。
比如说一些开发团队对于什么是架构设计,什么是好的开发实践一无所知,代码一团糟。
这样产生的债务是最危险的,因为既没得到技术债务的收益,还要偿还其产生的利息。
<li>**谨慎/无意的债务**<br>
这个象限反映了团队其实很重视架构设计和技术债务,但因为业务的变化,或者其他客观因素的原因,造成技术债务的产生。</li>
比如说最初设计的时候,无法准确预测后面业务的发展,随着业务的发展,设计无法满足好新的需求。
这样产生的债务难以避免,但如果能及时的对架构升级、重构,就能保证不会造成严重的影响。
以上就是软件项目中的四种技术债务,每一种技术债务产生的原因都不尽相同,对其处理的策略不同,也会造成不同的影响。
## 如何管理技术债务?
既然技术债务有利息也有收益,那么我们怎么能保证软件项目中的收益大于支付的利息呢?
Martin Fowler画过一张图来形象的描述了设计、时间和开发速度的关系。没有设计直接写代码从短期看确实是节约时间的但是跨过一个临界点后开发速度会急剧下降。
[<img src="https://static001.geekbang.org/resource/image/79/16/7951ea8fb6d669260055ab07c624fb16.png" alt="" title="图片来源Is it worth the effort to design software well?">](http://martinfowler.com/bliki/DesignStaminaHypothesis.html)
技术债务的收益和利息也是类似的道理,最初的时候,利息低收益高,欠一些技术债务是会节约时间的,但是超过一个临界点后,利息高收益低,就会大大降低开发效率。
所以最好能让技术债务控制在临界点之下,这就要求我们能充分了解目前项目中的债务情况,然后才好制定相应的策略,从而达到控制债务的目的。
#### 识别技术债务
如果是现实中的债务,查查银行账户就很容易知道是不是欠债了,而技术债务却没那么直观,但识别技术债务是很关键一步,只有发现系统中的技术债务,才能去找到合适的方案解决它。
你要是细心观察,还是可以通过很多指标来发现软件项目存在的技术债务。比如说:
<li>
**开发速度降低:**通常项目正常情况下在相同的时间间隔下完成的任务是接近的。尤其是使用敏捷开发的团队每个任务会评估故事分数每个Sprint能完成的故事分数是接近的。但是如果单位时间内能完成的任务数明显下降那很可能是技术债务太多导致的。
</li>
<li>
**单元测试代码覆盖率低:**现在大部分语言都有单元测试覆盖率的检测工具,通过工具可以很容易知道当前项目单元测试覆盖率如何,如果覆盖率太低或者下降厉害,就说明存在技术债务了。
</li>
<li>
**代码规范检查的错误率高:**现在主流的语言也有各种规范和错误检查工具也叫lint工具比如Javascript就有eslintSwift有SwiftLintpython有pylint。通过各种lint工具可以有效发现代码中潜在的错误和不规范之处如果错误率高则说明代码质量不够好。
</li>
<li>
**Bug数量越来越多**正常情况下如果没有新功能开发Bug数量会越来越少。但是如果Bug数量下降很慢甚至有增多的迹象那说明代码质量或者架构可能存在比较大问题。
</li>
除了上面这些指标,其实你还能找到一些其他指标,比如你用的语言或者框架的版本是不是太老,早已无人更新维护了;比如开发人员总是需要加班加点才能赶上进度,如果架构良好、代码质量良好,这些加班本是可以避免的。
#### 选择处理技术债务策略
在识别出来技术债务后,就需要考虑如何来解决这些技术债务了。解决技术债务有三种策略。
- **重写:推翻重来,一次还清**
将老系统推翻重写是很多程序员最热衷干的事情之一了。重写系统是一种优缺点都很明显的策略,这有点像你试图把债务一次性还清。
优点是你可以针对当前的需求和业务发展特点,重新进行良好的设计,精简掉不需要的功能和代码。缺点就是重写通常工作量很大,在新系统还没完成之前,同时还要对旧系统维护增加新功能,压力会非常大;另外新写的系统,重新稳定下来也需要一段时间。
- **维持:修修补补,只还利息**
维持现状,只对严重问题修修补补,这其实是常见的一种策略,就跟还债的时候只还利息一样。
修修补补相对成本低,不用投入太大精力,如果项目不需要新增功能,只需要维护还好,如果项目还持续要新增功能,越到后面,维护的成本就越高了。
- **重构:新旧交替,分期付款**
重构相对是一种比较折中的策略,就跟我们采用分期付款的方式偿还贷款一样。
每次只是改进系统其中一部分功能,在不改变功能的情况下,只对内部结构和代码进行重新整理,不断调整优化系统的结构,最终完全偿还技术债务。这种方式优点很多,例如不会导致系统不稳定,对业务影响很小。缺点就是整个过程耗时相对更久。
这三种策略并没有绝对好坏,需要根据当前项目场景灵活选择。有个简单原则可以帮助你选择,**那就是看哪一种策略投入产出比更好。**
无论选择哪种策略,都是要有投入的,也就是要有人、要花时间,而人和时间就是成本;同样,对于选择的策略,也是有收益的,比如带来开发效率的提升,节约了人和时间,这就是收益。
如果收益高于投入,那这事可以考虑做,否则就要慎重考虑。对一个生命周期不会太久,或者没有什么新功能开发的系统,花大力气去重构、重写是不合算的,不如维持现状。而如果有新技术新产品出现,可以以极低的成本替代原有系统,这样重写就是个好方案。
比如说我们项目中有个很老的自己写的CMS系统问题很多也没法维护于是最近找了一个开源的CMS系统把原有的数据一导入马上就很好用了也没有花多少时间。
通常,如果你纠结于不知道该选择哪一种策略时,那就选择重构的策略,因为这是相对最稳妥有效的。
#### 实施策略
当你选择好用哪种策略处理技术债务之后,就可以实施你的策略了。不同的策略可能实施方式上略有不同。
- 对于重写的策略,要当作一个正式的项目来立项,按照项目流程推进;
- 对于重构的策略要把整个重构任务拆分成一个个小任务放到项目计划中创建成Ticket放到任务跟踪系统中跟踪起来
- 对于维持的策略,也要把需要做的修补工作作为任务,放到计划中,放到任务跟踪系统中。
**实施策略的关键就在于要落实成开发任务,作为项目计划的一部分。**
#### 预防才是最好的方法
前面说的方法策略,都是针对已经存在的技术债务而言的。其实最好的方法是预防技术债务的产生。像下面这些方法,都是行之有效的预防措施:
- **预先投资:**好的架构设计、高质量代码就像一种技术投资,能有效减少技术债务的发生;
- **不走捷径:**大部分技术债务的来源都是因为走捷径,如果日常能做好代码审查、保障单元测试代码覆盖率,这些行之有效的措施都可以帮助你预防技术债务;
- **及时还债:**有时候项目中,因为进度时间紧等客观原因,导致不得不走捷径,那么就应该把欠下的技术债务记下来,放到任务跟踪系统中,安排在后续的开发任务中,及时还债及时解决,就可以避免债务越来越多。
如果团队能提高对技术债务的认识,防患于未然,就能让技术债务保持在一个合理的水平,不会影响到开发效率。
## 总结
今天,我带你一起了解了软件项目中技术债务的知识。解释了技术债务的概念,技术债务,就是软件项目中架构质量和代码质量的透支。
技术债务,也并不都是坏事,如果合理利用,就可以在短期内缩短时间,但是后期如果不偿还技术债务,也会对项目及个人造成不好的后果。
技术债务产生的原因有四个方面:轻率/有意的债务、谨慎/有意的债务、轻率/无意的债务和谨慎/无意的债务。
可以分三个步骤来管理技术债务:识别技术债务、选择处理策略和实施策略。处理策略有三种:推翻重写、修修补补和重构。
对于技术债务,是继续修修补补凑合着用,还是推翻重来?其实取决于哪一种策略的投入产出比更好,如果推翻重来代价太大,那么就应该谨慎考虑,不如先修修补补或者局部重构;如果修修补补难以维持,就要考虑重写或者重构。
对于技术债务,还是要在日常开发中有好的意识,不走捷径,防患未然,预防技术债务的发生。
## 课后思考
你现在的项目中,你能识别出来哪些技术债务?你打算采用哪种策略来管理你的技术债务呢?欢迎在留言区与我分享讨论。
感谢阅读,如果你觉得这篇文章对你有一些启发,也欢迎把它分享给你的朋友。