如何不混淆规范地图的键集和值集?

时间:2017-06-27 23:46:49

标签: clojure specifications

Clojure官方规范文件指出:

  

大多数用于指定结构的系统都会混淆规范   密钥集(例如,地图中的键,对象中的字段)与   这些键指定的值的规范。即在这样的   接近地图的模式可能会说:a-key的类型是x-type和   :b-key的类型是y型。这是刚性的主要来源   冗余。

在这个问题中:clojure.spec human readable shape?

给出以下示例:

(s/def ::car (s/keys :req [::tires ::chassis]))

(s/def ::tires (s/coll-of ::tire :count 4))

(s/def ::tire (s/or :goodyear ::goodyear}
                    :michelin ::michelin))

我的问题是:这怎么不是不可取而不是多余的?与此相反,那些刚性和冗余的东西(在Java中?)会是什么样的例子?

在我看来,你仍然无法定义一辆带有6个轮子的赛车,因为::tires必须有4个元素。你不能定义一个后轮将成为螺旋桨的浮动车。

从刚性和冗余的角度来看,上面的例子与静态打字有何不同?与使用car实例本身包含四个tires实例构建的Java tire类有什么不同?

基本上我认为我没有得到的是你通过告诉需要哪些键来指定地图。到现在为止还挺好。但是那些键是自己规定的,所以这些键指定的值也是指定的没有!?这里的事情怎么“没有混淆”?

1 个答案:

答案 0 :(得分:2)

暂时退一步,将软件开发视为一种做法。我们将在底部进行规范。

作为工程师,我们最重要的技能之一是能够在抽象中定义和思考

考虑功能组合如何简化复杂软件的构建。它允许我们更广泛地思考正在发生的事情,从而简化了复杂功能的定义。这样做的一个很好的好处是它还允许组成较大的函数的较小函数在编写类似但稍微不同的复杂函数时可以重用。

当然,您根本不需要 功能。您可以在一个函数中编写整个项目。但是,这是一个坏主意,主要是因为它将函数的 intent 与函数的规范混合在一起

例如,函数make-car调用build-enginebuild-drivetraininstall-interior等等。当然,您可以从每个代码中获取代码并将其粘贴到make-car中。但结果是你失去了抽象。除make-car代码本身外,make-car无法改进或更改。如何构建引擎的代码无法改进或重复使用以制作任何其他汽车。为什么?因为知道如何为构建 特定汽车规格的引擎嵌入make-car函数。

因此,make-car不应该定义如何来构建引擎(或汽车的任何其他组件);它简单地指定了汽车构成的组件以及它们如何协同工作。这些组件的细节不属于make-car中嵌入的工作知识。

现在应该明确与规范的比较:

以类似的方式,spec允许您将实体定义为抽象。你能在规范/模式中嵌入实体的知识吗?当然。您能否直接将各个组件的规范替换为实体定义本身?是。但是在这样做的过程中,您将实体与其组件的定义混为一谈。损失与上述相同:您失去了对实体的抽象,因为现在您必须更改实体的定义,以便更改有关实体的详细信息其组成部分;并且,你已经失去了重用定义的能力,用于类似但不同的实体。