
当我和我的朋友都已经上学并渴望成为软件开发人员时,我们梦想着一起设计一些很棒的东西,例如游戏或大型有用的应用程序。
我选择学习C ++和C#,他选择了JavaScript。 我们完成了学业,从大学毕业,在部队服役并开始了我们的工作。 我们在工业软件工程中度过了非常繁忙的时间,有很多不同的工作和职位,在这一切开始给我们穿上之后,我们回想起了一切。
终于成为成熟的开发人员,我们决定从事自己的项目-二维视频游戏。 由于我朋友的领域是前端领域,而我是全栈开发人员,因此我们即时选择的开发平台是Internet浏览器。 因为我在设计前端时只习惯使用TypeScript,所以我们认为没问题,毕竟TS只是大规模的JavaScript。 让我们使用它,一切都会顺利进行。 如果我只知道我错了! 当我们开始讨论该项目时,我们之间陷入了广泛的误解。
这是我对游戏的看法。 我当时想,好吧,我们有游戏,工具,物品,地图,位置等类型。 我对它们如何协同工作有基本的了解,因此我将对其进行描述,编译该项目-并且它可以工作。 毕竟,编译器已经验证了我的代码,而且我做对了。 接下来,我开始编写使用这些类型的代码。 它们使我的生活更加轻松。 我的IDE给我工具提示,并检查是否有错误。 如果可以编译项目,则可能可行。 我花了一些时间在类型描述上,并产生了结果。 简而言之,这就是我的方法。
我的朋友有相反的想法-立即跳到代码编写,而无需花时间描述类型。 他还没有准备好将问题定义为一系列类型。 他并不热衷于将其用作基础,因为他不认为问题是一组类,类型,记录之类的东西。 我认为这是不可思议的。 我们俩都有一个观点,只是我们的观点是相互排斥的。
说真的,我们聊了好几个小时,但每个人都在说自己的话,好像我们在说不同的语言。 请注意,我不能怪我们被困在旧的方式中。 就在一年前,我毫不费力地从面向对象编程的世界迁移到了函数式编程的世界。 此外,我花了相当长的时间学习JS,他-学习了许多静态类型的语言。
但是,对于任何开发人员来说,他们用于第一份实际工作的技术通常将其定义为,两个经验丰富的成年人根本没有耐心听对方讲话。 在这些年的软件工程中,我们的愿景以不同的方式塑造,以至于我们解决问题的方法无法很好地融合在一起。
最后,我们放弃了团队合作的想法。 您的第一个回答可能是问题出在我们的个性上。 您可能是对的,但我也看到了行业中其他人的情况。
静态和动态类型之间的根本性,不可调和的区别
我的代码为如何使用它提供了解决方案,而经验丰富的动态类型提倡者的代码则解决了如何使用它的问题。 两种思维方式都是合法的,并受到现有工具集的支持,但是在任何时刻,只有一种方式具有最高优先级。
静态类型适用于涉及数百名开发人员多年的大型项目,而动态类型适用于通常需要只写代码的小型团队和项目。 动态类型可让您在开发开始时节省时间和精力,而静态类型可在开发结束时为您提供帮助。
将类型放在首位的想法严重影响了我作为开发人员的想法。 在我职业生涯的开始选择了C#之后,我便将静态类型的硬编码硬编码到了我的思维定势中,现在我为此付出了这种僵化的代价。 看到任务后,我会尝试将其解决方案想象为一组关系类型和规则。 在开发模块时,第一步是定义其操作并用于与环境交互的类型。 我只是不记得在那之前我是怎么解决问题的。
学习用Java编程的整个过程都涉及学习设计和使用类型。 .NET CLR(C#运行时)建立在类型和类型上。 静态类型是面向对象编程范例的核心(您好,JS类,我决定稍作休息)。 大多数OOP模式的规范实现都被Interface关键字饱和,这在动态类型化的语言中毫无意义。
设计模式本身是跨语言的概念,但是谁能告诉我为什么在地球上我需要使用动态类型语言的State模式? 那Builder呢? 这些模式与开发无关,它们主要与类型有关。 类型和OOP有紧密的联系。
您不能在类型上建立业务逻辑,但是在开始编写代码时一无所知。 这就是为什么我们有一些前端开发人员为他们的代码提供大量单元测试,这些单元测试专门检查代码库是否存在类型错误。
我们都知道,基于代码覆盖率的保护只是一种幻想。 测试是手动编写的,并且从定义上讲,它们不如该语言提供的内置类型验证系统可靠。
这并不意味着动态类型化的语言没有意义(尽管我承认我确实认为它们没有意义)。 这意味着在使用它们时,您需要从OOP退后为主导范例。 数据和数据驱动的操作的所有这种统一是为具有静态类型的伙伴而设计的。
我遇到的开发人员认为静态类型不会在任何程度上影响编码方式,因此他们只是像使用动态语言一样编写代码,只添加类型检查。 我相信这本质上是错误的。 在现代前端的情况下尤其明显。
我知道,批评前端开发人员是忌讳的。 我和我的朋友曾经组建了一个吸引Twitter用户的AI机器人,而Brendan Eich对此表示强烈反对。 认真地说,JavaScript创建者在我们的神经网络中反复评论。
由于某些原因,这些家伙还没有准备好生活在他们的视力有明显缺陷的世界中。 这就是为什么我只批评那些篡改我绝对类型的项目的人,以他们轻松的“任何”方式进行修改的原因。
我们会一直生活在我们的小世界中,但是TypeScript将我们带到了一起
以我为例:由于类型限制,我的代码无法正确使用。 当我从事一个项目时,我也依靠其他人来使用类型。 然后,我的代码将按设计工作。 因此,我故意不涵盖此代码可能无法正确使用的所有情况(因为键入使得不可能)。 但是随后,一个JS开发人员加入了我的项目,接受了我的类型,将其包装在Any中,并开始不正确地使用它,从而导致难以复制的错误。
JavaScript开发人员相信TypeScript是相同的旧JS,但是可以选择添加静态类型检查(如果需要)。 错了 TypeScript的功能强大了一百倍,但是他们只对它的潜力感兴趣。
他们的杀手argument是TypeScript只是JS的超集。 在实践中,即使TypeScript是前端的疯狂之王,也不能忽视TypeScript是一种独立的语言这一事实。 因为它需要不同的方法-静态而非动态验证中的一种。
静态类型化的主要好处是可以为您提供保证。 如果在一个模块中使用它,而选择不在另一个模块中使用它,那么您将浪费时间和精力在描述和设计这些类型上,而没有任何保证。
许多人认为TypeScript是JS和Java之间的类型系统的折衷。 嗯,这不是任何妥协,它拥有自己的特殊类型系统。
最糟糕的是,今天有两个前端位置之一需要精通TypeScript。 这促使JS开发人员对TypeScript的功能一目了然,并立即跳入其中编写代码,从而产生了有害的做法。 发生这种情况时,他们实际上并不需要静态类型检查,但这是强加给他们的,所以他们弄乱了它。 我们最终需要承认,使用静态类型与动态类型进行编程的方法相互冲突,并且不能混为一谈。
我将JavaScript视为编写快速破解代码的绝佳工具,该代码可提供解决方案而无需找出不必要的抽象。 这里最可笑的例子是制冰厂模式。 您可以为它提供实例,它将实例包装为运行时不变性。 如果我通过这样的工厂处理对象,它将返回其等效对象,但是如果我尝试更改其属性之一,它将引发异常。 WAT?!?
之所以出现这种模式,是因为前端开发人员听说过一些关于酷不变性的知识,因此他们决定将这些东西拖入他们的语言中,这需要像一个头上的洞。 在TypeScript中,我可以设计一个类似的工厂,但是对突变进行编译时限制,并且没有任何例外。
另一方面,我几乎不需要它,因为这里有纯函数式编程。 以F#,Haskell,OCaml,Clojure,ReasonML为例-它们具有开箱即用的可变性禁止。 但是有什么告诉我,如果前端开发人员可以使用一种功能语言,他将愿意对其进行升级以使其行为类似于JavaScript。
那是因为选择您的打字宗教信仰是单程票。 解决方案之间的所有解决方案只能提供折衷的幻觉。 您要么依赖类型,要么不依赖类型。 我不知道如果我开始并行学习C#和JavaScript,我的生活是否会有所不同。 今天,我是如此无望地以自己的心态来识别自己,以至于我只是看不到动态类型的任何优势(也不想看到它们)。 它们存在,只是在我的能见度范围之外,所以我能做的就是像对任何我在这个世界上必须忍受的现象一样闭上眼睛。 我知道我做错了,但是我现在必须在这里工作,而且我没有足够的预算继续坐在篱笆上。
因此,我不想寻求妥协,相反,我会直言不讳。 如果您只是第一步,请从静态类型开始!