评估抽象

2020-07-21 12:15:56

一些抽象概念是定时炸弹,而另一些则帮助您快速移动。你怎么看得出来?下面是我个人对如何评估抽象的探索。

我们在程序中添加抽象来解决问题。那么,让我们从基本的价值主张开始:我们的抽象解决了什么问题?

这可以是一种自然语言处理抽象,它允许我们提取一段文本,并从中提取含义。自然语言处理的固有问题相当复杂,因此帮助我们解决它的抽象将是非常有价值的。这是一个很好的抽象的标志。

也许这个抽象在string.plit之上添加了一层轻层。例如,它可以使您不必担心正则表达式,并且可以将常见的字符串模式转换为正则表达式。StringSplitter抽象的价值非常低。也许StringSplitter对待分裂Str的方式更符合某人的想法,但归根结底,这是一种间接的方式。

这将我们引向第一个原则。它为您解决的问题越复杂,抽象效果就越好(1)。

在我们确信即将添加的抽象为我们解决了一个难题之后,下一件要考虑的事情是接口:我们如何与抽象交互?想象一下,如果NLP.parse是这样调用的:

这是一个很棒的界面。它很小。我们不需要了解任何内部结构。对于主要用例,我们需要做的就是提供语言和文本。将其与。

为了使用这个版本,我们需要深入了解NLP.parse的内部结构。这降低了抽象的价值,因为我们需要做更多的工作来解决相同级别的复杂性。

现在我们有了一个具有解决难题的简单接口的抽象,我们需要问一个可能致命的问题:当我们需要突破抽象时会发生什么?

所有抽象在某种程度上都是有漏洞的。当您需要抽象以不同的方式运行时,会发生什么情况呢?如果它没有像您预期的那样工作,会发生什么呢?

例如,对于NLP.parse(lang,text),如果我们需要对结果进行不同的排序和评分怎么办?如果有bug,而我们没有得到我们期望的实体,我们可以查看并调试吗?

理解了这个问题的答案,将会给我们带来突破性的成本。要做到这一点,我们需要使代码达到峰值。NLP.parse是如何实现的?

在一个解决方案中,它可以由我们可以利用的其他抽象组成。这是一个很好的迹象,因为我们可以在需要做更复杂事情的情况下重用底层抽象。将其与。

这感觉更危险。如果这些标志都指向同一个函数,则表明一系列不同的功能一起完成。同样令人担忧的是:如果其中一面旗帜没有做到你想要的怎么办?您可能必须对抽象进行分叉。

这就引出了第三个原则:伟大的抽象是透明的。我认为这个原则是最被忽视的。预先赢得生产力是很容易的,但是如果您添加的抽象不能改变,也不能内省,那么它很可能会在某个时候咬住您。

最后一个原则与后三个原则是正交的,但它可能是最重要的。哈代说,丑陋的数学在世界上没有永久的位置-抽象也是如此。数学之美与解的“一般”和“严密”程度有关。我认为这与抽象很相似。

如果您使用“本质上”更简单的抽象,它更有可能持久,而且可能更强大。

考虑一下NLP的抽象是否由特定的算法组成,仅用于自然语言处理。这仍然是非常有价值的,但是更有价值的是,如果这个库所组成的抽象更通用:如果组成它的部分是深度学习抽象,您可以重用它们来解决其他问题。

我们就到了尽头。挑选伟大的抽象概念:挑选那些能为你解决复杂问题的抽象概念。确保他们有一个简单的界面,并看一看内部结构,这样你就有信心在需要时可以拼凑起来。在相同的功率下,你能得到的东西越普遍、越简单,就越好。

想看看野外的一些伟大的抽象作品吗?首先,您可能正在使用其中的许多功能:TCP、更高级别的函数,如map&;filter、REACTION。有些您可能还没有研究过:Go的CSP、Rich Hickey的Datonomic或他在Clojure中的序列抽象。当您开始学习抽象概念时,我鼓励您将每个抽象概念作为一个实验来运行:在结束时问问自己事情进展如何,与您的朋友讨论它们,很快您就会培养出更加微妙的品味。

(1)兔子洞变深了。即使抽象解决了您的复杂问题,您也可能需要后退一步,并问一问:为什么我会有这个问题?例如,Kubernetes可能是构建分布式系统的一个很好的解决方案,但是为什么会有分布式系统的问题呢?很多时候,问题本身是可以避免的。对于这个问题的答案,“黑客天堂”试图对其进行报道。

感谢Alex Reichert,Daniel Woelfel,Martin Rison,Sean Grove审阅本文草稿