在基本的面向对象编程中,只能直接调用一个类的方法,而这些方法是由这个类的作者定义的。上课没问题。另外,在20-30年前,在大型标准库和开源库被大量重用之前,大部分代码通常与您自己的代码中的类一起工作——也就是说,由您自己的团队或公司代码维护。然而,在现代编码世界中,我们经常使用其他人编写的类。业务逻辑通常会大量使用包括字符串和集合在内的标准库函数,以及第三方库中的一些类,而我们受限于这些类提供的操作。例如,当我们需要用破折号替换字符串中的空格时,我们会这样写代码:string.replace('','-')但是当我们需要将左边的字符串对齐到指定长度时,我们可能没有现成的方法可用。在这些老语言中(比如Objective-C、C++、Java或者JS),你需要强制把它写成这样的形式:leftPad(string,'',length)这个leftPad可能来自一个单独的库1,也可能来自第三方实用函数集合(比如ApacheCommons),或者自己写在自己的项目中。不管怎样,它的调用看起来与String类的内置方法非常不同。为什么会出现这样的问题?我引用了Java的作者之一盖伊·斯蒂尔(GuySteele)在他1998年的《成长的语言》论文2中的话。在大多数语言中,用户至少可以定义一些新的语法来表示另一段代码,然后方便地调用这段代码,这可以使新语法看起来像原生调用。通过这种方式,用户可以构建更大的语言来满足他的需要。GuySteele,GrowingaLanguage他批评APL缺乏这样的设施,但同样的批评也适用于现代环境中旧的面向对象语言。您被原始库的设计者设想的类操作词汇所困,您无法对其进行扩展。此外,它不能被广泛使用的库的维护者任意扩展,再次引用同一篇论文的内容作为原因。编程词汇的某些部分适合所有程序员,而其他部分只适合少数人。程序员需要了解它的所有词汇用法是不公平的。C#、Scala、Rust、Kotlin和Swift等现代语言通过支持扩展方法解决了这个问题。您可以将特定于域的扩展方法添加到不受您控制的类中,这样您自己的函数就可以像内置方法一样被调用,而您的代码仍然以散文式的、从左到右的顺序阅读.string.padLeft('',length)这个padLeft扩展可以在任何地方定义,这是一个编程语言进化的好故事。然而,不仅如此。一旦编程语言支持扩展功能,它就改变了API设计的经典面向对象方法。对于从Java这样的旧语言切换到Kotlin这样的现代语言的程序员来说,这是一个启示,因为扩展函数通常只是作为方便的语法糖呈现。让我们从查看具有一堆属性(或getter方法)的接口开始。interfaceObscure{valfoo:Intvalbar:Intvalsum:Intvalmax:Intvalmin:Int}它与您在典型的商业应用程序中找到的接口或类没有什么不同——有一堆属性和方法.你能快速掌握这个接口代表什么样的实体吗?哪些属性构成了它的状态空间?如果没有额外的文档,要弄清楚这一点并不容易。但是让我们把这个接口重构为一个核心实体和方便的扩展功能。interfaceNotObscure{valfoo:Intvalbar:Int}valNotObscure.sum:IntvalNotObscure.max:IntvalNotObscure.min:Int现在,很明显这个接口的核心功能包括两个整数属性foo和bar,而剩下的sum,max和min属性只是为了方便而提供,并且是在这些核心属性之上计算的。无需明确记录这种区别——从代码结构中可以直接看出这一点。这种面向扩展的设计在Kotlin标准库和第三方库中被广泛使用。这是一种强大的设计技术,可以用来产生很好的效果。这种设计方法有副作用。您可能会注意到Kotlin代码经常使用通配符导入,例如importcom.examplease.*。这在Kotlin中很方便,因为在Kotlin中很少只导入一个类。所有有用的、方便的、实用的函数通常都定义在同一个包中,但在类之外作为扩展函数。文章中的链接:https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/一位开发人员如何用11行JavaScript破坏Node、Babel和数千个项目,ChrisWilliams,2016https://万维网。cs.virginia.edu/~evans/cs655/readings/steele.pdfGrowingaLanguage,GuySteele,1998https://kotlinlang.org/docs/reference/extensions.htmlExtensionsinKotlinProgrammingLanguage英文原版:https://medium.com/@elizarov/extension-oriented-design-13f4f27deaee本文转载自微信公众号“高可用架构”,可关注下方二维码。转载本文请联系高可用架构公众号。
