这是一篇综合类技术选型指南,试图为你提供一份比较通用的技术选型思惟框架。当你须要进行技术选型时,能够参照它来设计本身的决策树。这其中你须要考虑的主要维度包括目标产品、目标用户、目标团队和技术自己,下面我将分别细述,并在此基础上介绍一些反模式。前端
这是最重要的维度。产品自己的特征将影响技术选型时的不少因素。程序员
短生命周期产品和长生命周期产品编程
短生命周期的产品一般要求快速起步:门槛低、书写自由、不强制遵循任何最佳实践。当它的使命结束时,代码会被直接抛弃。因此,对于这类产品,“快糙猛”的技术是较好的选择,固然,能作到“快精猛”更佳。后端
而长生命周期的产品则会强烈要求可维护性,由于它们在很长时间内都是不可报废的。甚至对于一些生命线产品,连重写都会要求在重写期间线上系统平稳过渡,一点点迁移到新技术。浏览器
这种要求对团队的工程化能力是个极端的考验。若是没有相应的工程能力,其代价甚至会高于用新技术从新写一个功能相同的系统。微信
探索型的产品和守成型的产品架构
探索型产品每每也是短周期产品,可是同时也有本身的特色。它要求快速,但每每同时会要求高质量。探索型的产品若是证实了可行性,那么过渡到长生命周期的可能性很大。框架
这就要求它最好是一个微内核系统,提早留出一些扩展的空间。固然,设计微内核系统对架构师的能力具备至关的考验,若是没有一个优秀的架构师,建议仍是不要刻意作任何预留,优先保障系统的简单性。运维
除此以外,探索型产品的技术栈必须支持可靠的、自动化的重构。由于探索型产品的迭代速度很快,若是彻底靠人工去添加功能并手动重构,那么一旦出现 BUG,将给此产品的用户体验带来严重的负面影响。性能
因此,除非因为人才储备等缘由而被迫作出折中,不然探索型产品的技术栈必定要快速而严谨。
固然,“大力出奇迹”定律也是成立的。也就是说,若是你有决心也有力量在未来对这个探索型产品进行完全的重写,那么采用快糙猛的技术快速把它搭建起来,也何尝不可。若是你的业务确实能如预期般爆发,那么只要把重点放在系统延展性等方面便可;可是若是不能如预期般爆发,可能就会致使维护成本在中期开始飙升,在竞争中处于劣势。这是一种“不成功便成仁”的策略。据我所知某独角兽企业就是在业务起来以后经过巨额投入来偿还技术债的。但这对于 CTO 的技术直觉是一项极大的考验,不要轻易效仿。
而对守成型产品的选型则会侧重于与现有技术栈的类似程度和无缝整合能力。若是整合时须要借助不少技巧,那么可能你就是在给本身挖坑。
在引入新技术的过程当中,要尽量符合现有的开发流程、基础设施和开发习惯。固然,若是现有的这些已经严重过期,那么应该找新老技术的专家,共同帮你设计一个路线图,让你能够平稳地引入新技术,这份投资绝对值得。若是老技术已经有新版本,则应该优先考虑升级它。不要幻想换个技术栈就能解决一切问题,事实上,它带来的问题每每会更多。
边缘产品和生命线产品
在人员的学习能力和意愿容许的前提下,边缘产品是最佳的试验场,适合探索各类候选技术,试验各类激进方案,积累经验教训。其影响范围可控,即便失控也不会带来太大的损失。固然,即便探索,也应该有计划地探索,不要每一个边缘产品都采用不一样的技术方案,那样会给人才供应带来巨大的挑战。
而生命线产品则应该稳妥优先,采用保守方案。因此应该优先采用团队内部积累了必定经验或具备稳定的强力外援的技术。
全部的生命线产品几乎必然是长周期产品,因此其可维护性一样是重中之重。
产品维度总结
在目标产品维度上,低价值产品优先考虑门槛低的技术,可是高价值产品应该尽早进行投资性技术积累,优先考虑天花板高的技术,这样才不至于在若干年以后被迫重写。若是工程化能力不足,这种重写每每会成为灾难。
用户的特色对于技术选型具备显著的影响,甚至可能会致使产品不可用。
浏览器版本
在前端领域,浏览器版本是永远的痛,但这是须要权衡的。高版本浏览器甚至是单一的低版本浏览器会显著节省开发成本,可是可能会损失一些用户。该怎么解决呢?固然不能拍脑壳决定。
若是大家已经有同领域的线上系统,那么应该统计这些线上系统的访问状况,得出一个最准确的、针对目标客户群的统计,而后分析一下不一样版本的浏览器有多大价值,有没有可能经过非技术手段让用户使用大家的目标浏览器。即便没有线上系统,也能够随机对目标用户群发一些调查问卷,肯定他们的实际使用状况,以及安装新版浏览器的可能性。
下下之策是查一下百度公布的全网浏览器数据,而后说“咱们要支持某某浏览器,它还有 10% 市场占有率呢!”,这是懒。
用户带宽
一样是前端领域,文件的下载体积可能会被一些人当作亮点进行宣传,可是你要清楚,如今已是 4G 时代了,更不用说不少企业内部应用都是千兆带宽。就算能比候选技术小 100k,在 4G 带宽下(假设现实带宽是 2MB/s)也就是 100 毫秒,有谁能感受到这部分差别? 这就是一个明显的“误导读者”的例子。
可访问性
在产品的用户群体中,不但有健康人,还有色盲以及盲人等残疾人。特别是对于面向消费者的产品,尽量的考虑这些人的需求不但能体现出产品的“人文关怀”,并且也在必定程度上扩大客户群。好比苹果和微软等大公司都把可访问性放在了核心位置。若是你决定要实现可访问性,那么就应该把它做为一项需求,归入到选型时要考虑的因素中。
之因此要把它归入到技术选型过程当中,是由于添加可访问性支持的代价比较高,而不少第三方库并无提供这方面的支持。因此应该提前考虑。
国际化
与可访问性类似,国际化也是一个后期添加代价比较高,但不少候选技术却没有提供支持的特性。
若是你的产品在预期生命周期的至关一段时间内须要供多语言用户使用,那么,在初期选型时,就要把候选技术的国际化能力和质量归入你的主要考量。
访问频度
用户的访问频度对先后端的技术选型都有很大影响。
好比说一个一年只用一次的功能,考虑其性能极可能是没有必要的,在一小时内跑完和在一分钟内跑完每每没有显著的价值差别。可是这两种技术方案却可能有着硬盘占用、编程复杂性、运维复杂性等方面的成本差别。你须要考虑:那种能在一分钟内跑完的技术是否能给你带来足够的价值。
对于前端来讲,频繁访问的、面向消费者的应用一般会要求更高的流畅度,那么在技术选型时,就要选择流畅度更高的技术。可是这个流畅度必定要设计一个仿真的场景,亲自验证一下,甚至作一些灰度发布在现实场景下进行验证,而不要只看其官网宣称的流畅度。好比阿里的闲鱼团队就对 Flutter 技术进行了长时间的灰度验证,最终替换成了彻底使用 Flutter 的版本,堪称对新技术进行选型的模范。
用户维度总结
要特别当心,不要根据错误的、片面的信息做出决策。不少第三方的技术选型指南背后都有着它们本身的场景,但大多数都不会给你写清楚,有的甚至复杂到想给你写清楚都作不到。甚至有些选型指南还有着强烈的主观立场,为了证实本身的预设立场甚至不惜造假。因此,你要先清点出大家的产品最应该重视的那些指标,而后拿这些指标对候选技术进行可行性测试,甚至为此专门开启一些 SPIKE 项目,而不要迷信第三方选型指南。
目标团队的因素确实很重要,但并不像你认为的那么重要。除非你的人才供应真的有问题(难道不该该先反思一下是否是钱给少了?),不然应该优先考虑提高团队能力,而不是削足适履。
技术背景
目标团队的技术背景对新技术的选型确实很重要,可是不必去精确匹配。
好比 Java 团队要作前端,选择 GWT 看似很好,但 GWT 也有本身的问题,几乎彻底没法利用前端生态。他们更好的选择多是 Angular:从语言上,TypeScript 跟 Java 有诸多类似之处;从架构模式上,对 MVC 的理解稍微往前推一步就是 Angular 的 MVVM 模式;从特性上,依赖注入不要太熟悉;从生态上,你能够自由决定是否使用前端生态,取长补短。
一样,前端团队若是打算本身写 BFF,也不必定非要在 Node 生态下打转。你彻底可使用 Java 世界的 Reactor 或者 WebFlux 进行响应式编程。这样能够和后端的其它 Java 体系更好地进行集成,并减小运维的复杂度。
团队规模
团队规模多是团队维度中对技术选型影响最大的因素。
四位开发人员如下的小规模团队,若是你们都很专业,那么其沟通成本就很低,在技术选型上能够更倾向于选择灵活的技术,由于较高的人员能力和较低的沟通成本,可让灵活的框架更好地发挥其做用,最终更加高效、高质量的推出产品。这种场景一般出如今由牛人组成的创业团队中。
若是开发人员经验不足或者作事不够专业,就须要更强的约束,特别是对于职场新鲜人,在早期养成好的开发习惯是很是重要的。而开发习惯中最重要的一点就是:约束 —— 知道不应作什么。这时候,偏向自由的技术可能会一时爽,但最终会构筑一个玻璃天花板,致使迟迟没法突破到下一个层次。
若是团队规模过大,那么首要的选择是用 DDD 等宏观技术把问题域细分,使其能够被小规模团队承接。若是暂时还作不到,就要考虑建设完善的基础设施和交付纪律,来为团队协做提供自动化保障。若是这些都作不到,就应该选择强约束性的具体技术,让你们避免犯错,或者尽早发现错误。在争取到时间以后,再逐渐深刻化解根本性缘由。
组织架构
康威定律深入地影响着不少方面,技术选型也不例外。特别是作宏观技术选型时,必须考虑它在最终技术架构中的位置,以及与团队沟通结构的匹配程度。即便是一项很先进的技术,假如它与体系中的其它技术栈不匹配,也可能致使翻车。
当选择多个第三方库的时候更要加倍当心,由于它们开发时互相不知道彼此的存在,特别是对于一些较新的技术,可能都没人把它们搭配使用过。
除了开发架构以外,还要考虑更普遍的运维架构。假如大家引入了 DevOps,可能这个问题会获得必定程度的缓解。假如没有,那就要充分考虑上下游环节的人员能力和配套设施是否完备。好比若是运维部门缺少 NodeJS 运维技能,就不要盲目引入基于 NodeJS 的后端,必定要拿到他们“我能”的承诺以后再开始。
除非你是个先后端 + DevOps 全栈,不然就须要尽早对组织架构方面的因素进行验证并排除风险。也就是说,在一个可控的演习环境中,用一个小型案例,完整地走一遍开发、上线、发新版的流程。在这个过程当中,一些显著的风险将会暴露出来,要评估其影响,来决定如何选型。
人员流动性
人员流动带来的损失比大多数人所认为的要大得多。人员流动会带走知识和文化。企业要避免损失,就要把这些知识和文化尽量记录在代码中。
固然,这并不意味着应该要求大量写注释,而应该使用那些能留存知识的技术,好比类型系统和规范化命名。类型系统和规范化命名能够半强制性地要求开发人员把本来只存在于本身脑子里的知识记录到代码中。若是更有追求一点,能够再尝试普及单元测试。这样,当他离开的时候,即便没有文档,这些知识也仍然能留存下来。从效果上说,代码每每比文档和注释更好。
而文化的留存则更加困难,事实上,代码中的奇葩注释每每留存的是负面文化。应该在代码中留存的文化,是严谨、专业的工做态度。虽然自由也是文化的一部分,甚至在管理领域是很是值得向往的文化,但在工程领域,它每每是一种负面文化,由于软件开发领域并无公认的法律甚至道德。你能够想象一下管理领域中没有约束的自由会致使怎样的后果。
因此,要想应对人员流动的风险,除非你有信心留存知识与文化,不然就应该在技术选型时,倾向于选择更加严谨的、隐式信息更少的技术。
团队维度总结
鞋子好很差,只有脚知道。错误的选型,也只能由团队自身来承受。阿波罗神庙上镌刻着一句警世名言——了解你本身。因此,请先客观认识本身的团队,而后再据此进行选型,千万不要懒于思考,盲从潮流。
对技术自己的考量,主要是代入其它维度以后,看其匹配程度。
技术自己在选型中可能反而是最不重要的一个维度。这些年的历史早已证实:优秀的技术未必能流行起来;不少技术的流行,也并不是是因为其优秀。
明确的定位
一项优秀的技术,应该有其明确的定位和发展路线。这些定位能清楚地代表本身要作什么、不作什么。而其发展路线应该至少有一年以上的提早规划,并且在定位上要能与其前辈作出有效区隔,而不是亦步亦趋,没有本身的特长。
代码质量
虽然流行的未必优秀,优秀的也未必流行,但技术选型不是赶时髦。因此,在条件容许的状况下,仍是应该尽量选择优秀的技术。代码质量高的技术,未来技术自己因为维护成本飙升而被放弃的可能性也较小。
衡量代码质量的标准有不少,其中最经常使用、也比较有效的是单元测试的覆盖率。而那些从一开始就具备比较完备的单元测试的代码库,每每优于后补测试的代码库。由于这证实的是开发组的工程化能力和意识,而这些是该技术长期可维护性的根本保障。固然,除非该技术特别复杂或应用场景的容错性特别小,不然也没必要苛求超过 90% 的覆盖率。
维护团队
维护团队的规模和能力,对于一项技术在长跑中的表现很是重要。在历史上如流星般划过的技术数不胜数,但最终能长期留下来的却很少。维护一项技术的成本远高于建立它,因此若是没有一个健康、可持续的商业模式,一个像 Linus 那样的志愿者,以及一个愿意出钱的超级大金主,那么它在将来的竞争中落败只是早晚的事。除非这项技术的需求集足够小而稳定,不然这些因素缺一不可。
社区
社区的质量,决定着这项技术长远的将来,一些草根型技术的隐患就在于此。若是社区人员的素质太低,喜欢无原则的站队,而不能理性的对该技术提出尖锐的意见甚至批评,那么这个社区早晚会衰落。这类社区有一个显著地特征就是喜欢宣扬它“包治百病”,也就是说它适合一切场景,而不会先问你一些问题再决定是否要推荐给你。另外一个特征就是喜欢经过刻意选取某些标准来作出片面的对比,这种行为在学术界属于学术造假行为,但在咱们工业界却被习觉得常,这不能不说是咱们的悲哀。
好的社区应该是一个君子社区。他们会自觉遵照共同的、理性的行为规范。会把精力放在对技术自己作贡献,而不是经过诡辩、群殴等手段来攻击竞争技术。社区的主要领导者会对社区的不良行为提出批评、作出约束,甚至为社区成员的不良行为道歉,而不是听任无论。
技术维度总结
不要把技术看得过重。对全部的主观性宣传文章,留一些心眼,多问一句——那缺点呢?未来决定大家是否会掉在坑里的,就是它的缺点。
对于那些会如实告诉你缺点的宣传文章,请高看一眼,由于做者是真的但愿对大家团队的将来负责。
对于功利社区,请务必当心;对于君子社区,请自觉维护。
有一些技术选型策略可能会致使灾难性的失败,这些选型中存在一些共同的反模式,好比:
人云亦云,盲目听信外人或者某些布道师的主观性言论,这就是舆论驱动选型。它每每会带来灾难。
作任何决策时,若是要借助参考资料,请记住:最重要的不是它告诉了你什么,而是它对你隐瞒了什么,这些隐瞒的信息最终会置你于险境。
特别是当该资料的做者对某项技术具备显著的倾向性时,请深刻想一想,他向你推荐的每一项优势是否真的“对你”有价值,以及它背后的代价是什么。好比,推崇“自由”的技术每每不够“严谨”,若是你的产品须要严谨,那么请把“自由”看作减分项而不是加分项。好比,推崇“体积小”的技术在如今动辄几T硬盘、几M带宽的环境下,到底对你来讲有多大价值?它是否是由于没有其它的优势了才把这种细枝末节亮出来吸引你?
即便是调查报告之类的客观参考资料,也须要了解其背景。好比一份只发给程序员的调查报告,可能会发现 Chrome 的使用率超过了 99%,但显然它对你的面向普通用户的产品毫无价值,只会给你带来风险。同时,要注意不少调查报告的设计是有主观倾向性的,甚至题目的排列顺序都会给最终结果带来 10% 以上的误差。因此,必定要仔细分析其中立性、客观性以及调查对象在你的目标场景下的表明性。
根据任何一个单一指标进行选型都会给你带来灾难,更况且不少指标并不适合做为选型的依据。
有些指标很容易操纵,好比 GitHub 仓库上的 Star 就是很容易操纵的,在淘宝网上还有专门购买 GitHub Star 的服务,而 GitHub 的年度报告中也已经再也不把 Star 做为主要指标使用。即便是那些不容易造假的指标,好比 commit 数量,其实也不适合做为主要指标使用,它可能意味着做者具备良好的工程习惯和足够勤奋,但也可能意味着代码库质量堪忧,所以不断推出补丁。
固然,有一些客观指标仍是比较适合做为主要指标来使用的,但也不要盲目相信数字。好比单元测试中覆盖率较高的项目,确实一般质量比较好,可是我也见过一些只有调用却没有断言的测试,那些测试的覆盖率也会很高,但倒是假的。因此,若是要评估其质量,最好仍是亲自打开看一看。
即便你选出了一些主要指标,而且确信它们没有造假,也仍然不能简单地把它们加起来或加权平均来得出一个数字进行比较。你要综合评估这些指标对你的目标产品、目标用户、目标团队的价值。若是技术选型只是个数字游戏,那还要你干吗?
这几乎是最糟的选型,但却家常便饭。技术栈的更迭每每会带来话语权的变化,而这将给公司带来灾难。
对于高级技术决策者,须要有战略定力,应该以一种规范的、用事实说话的方式来控制技术选型的反作用。我曾见过一帮程序员“偷袭珍珠港”致使架构师被迫辞职的惨剧,我当时的意见是:这是 CTO 的锅。团队因为选择技术栈而产生了话语权之争,说明制度设计和文化建设出了大问题,这只能由 CTO 背锅。
因此,若是你是个技术决策者,那么应该尽早站出来,发挥你的职权和非职权影响力,抑制这些负面文化,而不是任由其发展,最终破坏公司的整体技术路线,甚至技术氛围。
对于生命线产品,最糟糕的选型莫过于粉丝驱动选型了,此次可没有“几乎”。对于技术人员来说,最重要的特质是客观冷静,这样才能配得上“专业”二字。而拜大神,看成玩笑尚可,若是让它影响到你的决策,那么你就应该趁早隐退了,省得未来被迫引咎辞职。
虽然也曾被人称做“大神”,但我通常会提出反对,至少不做正面回应。我已工做二十多年,太清楚业界百态了。实际上,不多有人真的配得上大神的称号,举世可能只有 Anders Hejlsberg、Bob 大叔、Martin Fowler、Jeff Dean 等少数几位。不过我相信若是你当面叫他们大神,他们也会反感的。
就算是对于这些举世公认的大神,也不该该成为你技术选型的依据,顶可能是相信他们会珍惜名誉、不会粗制滥造而已,由于即便是精品也仍然有着明确的适用范围,超出这个范围它也可能会成为毒药。
固然,对于边缘产品,进行粉丝驱动选型也何尝不可,甚至可能更好。只是得记住,要作就请作好,别给你的偶像丢脸,更不要作好以后就以为公司必定要把它应用于生命线产品中。
若是我在这篇文章的最后部分给你一棵决策树,你会不会很高兴?
很抱歉,写这一章的目的,就是为了告诉你:我不会给你任何决策树。请根据我提供的思惟框架,自行设计适合大家本身的决策树,及时更新它,而且不要盲目相信量化的评估结果。
文/ThoughtWorks汪志成
更多精彩洞见,请关注微信公众号:ThoughtWorks洞见