typescript get方法_TypeScript系列(六)TS不是银弹

typescript get方法_TypeScript系列(六)TS不是银弹_第1张图片

前言

在软件工程领域,"银弹"一词最早出现在小弗雷德里克·布鲁克斯的《人月神话》中。银弹本身是一种可以有效杀死狼人的唯一手段,后来被泛指为解决一个问题的灵丹妙药。今天,这篇文章不会像《人月神话》一样讨论软件工程的复杂性,而是重点关注TypeScript是如何降低软件工程中的困难的。

在接触TypeScript之前,主流媒体上一直贩卖着某种焦虑,比如TS是未来、是趋势,都2019年了,你们项目怎么还停留在JS。如果把这句话放在热门的房地产领域的话,可以这么说,都2019年了,有房是未来、是趋势,你们怎么还没买房。这句话可以说是错的离谱了。首先,买房没有必要性,人生的意义不是由房子提供的,其次,买房没有充分性,掏空六个钱袋都不够。对于前端项目而言,使用TS既没有必要性、也不一定有充分性。

有自己的房子住是极好的,在项目上能够使用TS也是极好的,这个毋庸置疑。看到这儿读者可能要问题,既然你赞成使用TS,还在这儿废话什么。这篇废话的主要目的是消除焦虑,以便从自身经验出发,给尚未接触和使用TypeScript的个人和团队一些更为理性的信息。

软件工程的困难

在谈TypeScript之前,我们先来回顾一下软件工程。我理解的软件工程是一个将业务模型抽象并具体化到软件工具的过程。在这个过程中,程序员扮演着把产品模型映射到可构建为软件工具的代码模型的角色,BA(Business Analyst)或PM(Product Manager)扮演着把商业模型映射到产品模型的角色。这个分工看似明确,实则困难,这种困难的表现形式多种多样,有996的、有延期的、有质量太差、有无法使用的。

小弗雷德里克将这些困难分为两类,本质性困难和附属性困难。

本质性(essence):软件本身在概念(conceptual)建构上存先天的困难;亦即如何从抽象性问题,发展出具体概念上的解决方案。
附属性(accident):将概念上的构思施行于电脑上,所遭遇到的困难。

附属性困难往往被更多人关注,比如:招聘更有能力的程序员,加班加点写代码,使用更高效的语言和工具等等。然而本质性困难却鲜有人关注。比如:产品定位不清晰、产品用户不明确、用户流程摇摆不定、团队知识文档一团乱麻等等。国内的互联网公司由于一些主官或客观因素在概念上的解决方案投入不足,导致更倾向于使用附属性困难寻找解决本质性困难的方法(勤能补拙),这样的策略在资金充裕的情况下能够维持,但面临经济寒冬,这样的方式无异于饮鸩止渴。

回到TypeScript。TypeScript能否有助于我们改善这两类困难呢?下面我将从这两类困难出发,来给出这个问题的答案。(从下面的分析来看,将困难简单地划分为附属性和本质性其实有点难以界定,本人认为这么简单的划分有点过时)

附属性困难

得益于搜索引擎,解决附属性困难对这年代的程序员来说问题都不大。唯一值得讨论的是效率。

大多数人都写过作文,对大多数人而言,写作文是件非常煎熬的事情,尤其在考试时间内构思出一篇作文。写代码和写作文很类似,都是一种完全的思维活动。对于写作文,很多老师总结出一种万金油套路,比如总分总,中间再插点小故事。但就算老师告诉我这种套路,但仍然很难在考场上写出一篇好作文。除过文法、词汇量对写作文的影响,我觉得最重要的因素是阅读量少,脑子中没有积累足够的素材。

同写作一样,写代码的过程也需要掌握"文法词汇"、"套路"和"素材"。编程中的"文法词汇"是对某种编程语言的掌握程度,这是基本功。"套路"是业务模型中的设计模式和计算模型中的算法。"素材"是对各类工具库的熟练程度。

那么TypeScript在这个过程中扮演的什么角色呢?我认为它扮演着拼写检查和输入法的角色。拼写检查能够帮助我们构建没有语法毛病的句子,输入法能够帮助我们快速定位词语,它能够稍微提到我们的打字速度,但写作文的瓶颈在于构思,因此,它对效率的贡献微乎其微。

总结一下,TypeScript能够分析程序的类型问题,并能够帮助我们快速定位我们需要的属性或方法。但它对写代码的效率贡献不高。写程序的效率更多地取决于对编程语言、设计模式、算法和库的熟练程度。

本质性困难

为了解决本质性困难,人们发明了瀑布式开发模型,并发明出了UML这种工具,试图在开发之前构建一个抽象的、完美的业务模型。这种尝试是非常值得肯定的,但渐渐地,人们发现开发软件是个渐进的过程。随着软件的成长,原先使用UML定义的文档已经毫无价值,甚至产生误导。

之后,敏捷模型被提出,自此,软件开发走上的光明大道。对于如何形成概念上的解决方案,敏捷给出的答案是,根据用户流程,将软件过程拆分为Epic,然后将Epic拆分为Story。对于如何保证概念上的解决方案符合技术约束,敏捷给出的答案是估点和IPM。对于如何保证概念上的解决方案能够成功映射到代码模型上,敏捷给出的解决方案是Kick Off和Desk Check。

这些敏捷实践从流程上约束了从抽象问题到概念模型的过程中出差错的可能性。但如何约束从概念模型到代码模型的过程呢?敏捷给出了答案,那就是重构、Tech Huddle、Code Review和TDD。这些实践好是好,但效果因人而异。对于同样的问题,微软也给出了一个选项,TypeScript。TypeScript好是好,但效果也因人而异。下面我们将讨论,TypeScript对于解决这个问题交了一份怎么样的答卷。

作为文档的TypeScript。在很多编程教材中,作者都不遗余力地强调这么一件事实,代码首先是写给人看的,其次才是机器。为了达成这个目的,开源社区发明了这些工具,代码格式化(prettier)、静态检查(lint),也发明了一些命名规范,来帮助我们更容易地阅读代码。良好的命名能够告诉我们是什么,逻辑怎么样,但无法告诉我们长什么样。TypeScript在这种情况下就能很好地帮助我们。从TypeScript的路线图来看,它也是作为一种提供文档的工具来开发的。在小型团队中,这类知识可以通过口口相传来解决,但对于大型团队,口口相传的效率过低,这时,使用TypeScript就显得十分必要。

作为抽象过程的TypeScript。在很多算法教材中,作者倾向于使用伪代码来描述算法的过程。这样做有个好处,让读者能够在接触编程语言之前理解这个计算过程。TypeScript也有同样的效果。我们可以像使用伪代码一样使用TypeScript,比如在开始编码之前就用类型定义好功能模块和接口,如果类型能够编译通过,再实现相应的细节。这样的过程有助于我们对功能进行拆分,并且拆分的结果(类型定义)深入在代码中,在软件的整个过程中始终提供价值。这个过程我们可以总结为TDD(Type Driven Development)。

缓解过度抽象的TypeScript。由于JS的灵活性,前端代码充斥着函数重载和过度抽象。这里的过度抽象指的是,为了削减重复代码,强行将逻辑或业务不想关的部分强行组织在一起的行为。举个极端的例子,你写了个常量10是代表10秒,他写了个常量10代表10米,然后10都是重复的,代码最终被抽象为一个常量。举个普通的例子,很多开发觉得写Redux的Action有点重复,它的作用就是异步获取数据,然后就将这个行为抽象为GET_ASYNC_DATA的Action,这样做虽然不写重复代码了,但为debug和理解业务带来了更多的困难。这类过度的抽象一般存在显著的特征,就是输入多变,没有约束,输出也无法预料。在使用TypeScript后,能够一定程度上能够抑制这类过度的抽象。因为TypeScript提倡对泛型进行约束,并且只能对约束过后的属性在函数体内操作,对输出的类型只能基于输入的类型做有限的操作。但TS不是灵丹妙药,因为存在asany这两大法宝。

有助于培养良好编程习惯的TypeScript。JS中存在很多隐式的类型转换,尤其是string和number之间的隐式转化最让人头疼。TypeScript有助于让我们思考如何将这类隐式转化消灭在源头。它也有助于让我们对第三方接口的类型有更清晰的认识,而不是可以工作就可以了。

总结

写了这么多,总结一下。TypeScript是个好东西,但好东西一般都需要一个好的实践去约束它才能够发挥价值。类型系统能够最为团队知识的沉淀,但它不是灵丹妙药,也无法替代敏捷实践。一个组织良好的团队首先应该关注的是敏捷实践,以降低本质性困难,这时,如果有TypeScript,能够锦上添花。

最后附上本系列的GitBook链接:

https://li-yu-1.gitbook.io/typescript/​li-yu-1.gitbook.io

参考文献

  1. 没有银弹 No Silver Bullet

你可能感兴趣的:(typescript,get方法)