Clojure 如何避免将规范与x27混淆;教育地图';s键集和值集?

Clojure 如何避免将规范与x27混淆;教育地图';s键集和值集?,clojure,specifications,Clojure,Specifications,Clojure官方规范文件规定: 大多数用于指定结构的系统都将 具有 这些键指定的值的规格。即在这种情况下 接近映射的模式可能会说:a-key的类型是x-type,而 :b键的类型为y型。这是刚性和稳定性的主要来源 冗余 在这个问题上: 给出了以下示例: (s/def ::car (s/keys :req [::tires ::chassis])) (s/def ::tires (s/coll-of ::tire :count 4)) (s/def ::tire (s/or :goodyea

Clojure官方规范文件规定:

大多数用于指定结构的系统都将 具有 这些键指定的值的规格。即在这种情况下 接近映射的模式可能会说:a-key的类型是x-type,而 :b键的类型为y型。这是刚性和稳定性的主要来源 冗余

在这个问题上:

给出了以下示例:

(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轮的牵引车,因为轮胎必须有4个元素。你不能定义一辆后轮是螺旋桨的浮动汽车

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


基本上,我认为我不明白的是,你是通过告诉哪些键是必需的来指定地图的。到现在为止,一直都还不错。但是这些键是自己指定的,所以这些键指定的值也被指定了。不!?这里的事情怎么能“不合并”呢?

请稍等片刻,缩小范围,将软件开发视为一种实践。我们会在底部找到规格

作为工程师,我们最重要的技能之一是在抽象中定义和思考的能力。 想想函数组合如何简化复杂软件的构造。它简化了复杂函数的定义,允许我们更广泛地思考正在发生的事情。这样做的一个好处是,它还允许在编写类似但略有不同的复杂函数时重用组成较大函数的较小函数

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

例如,一个函数
make car
调用
build engine
build drivetrain
install interior
,等等。当然,您可以从这些代码中提取代码,并将它们粘贴到
make car
中。但结果是你失去了抽象性<除了在
make car
代码本身中,不能对代码>make car进行改进或更改。关于如何制造引擎的代码不能被改进或重复使用来制造任何其他汽车。为什么?因为在
make car
功能中嵌入了如何为特定规格的汽车制造发动机的知识

因此,
make car
不应定义如何建造发动机(或汽车的任何其他部件);它只是指定组成汽车的部件以及它们如何协同工作。这些部件的细节不属于
make car
中嵌入的工作知识

与规范的比较现在应该很清楚了:
以类似的方式,spec允许您将实体定义为抽象。您能否将实体的知识嵌入到规范/模式中?当然能否直接将单个组件的规范替换为实体定义本身?对但在这样做时,您将实体与其组件的定义混为一谈。损失与上述相同:您失去了对实体的抽象,因为现在您必须更改实体的定义,以便更改实体的细节,这些细节实际上是其组件的细节;而且,您已经失去了为类似但不同的实体重用定义的能力。

感谢您提供了详细的答案,但我真的不明白。这个例子不是我的:这个汽车例子来自另一个SO问题的答案。该汽车示例是否将汽车实体的定义与其轮胎组件的定义混为一谈?这与Java Car类有什么不同?Java Car类的构造函数将采用轮胎实例?@CedricMartin(1/2)是的,Car示例是我的,我承认它可能会更好。但是,这样想:如果我们想改变轮胎组件的细节,汽车实体的定义会改变吗?不。因此,这两者完全是解耦的,以至于组件的规范甚至不需要存在才能规范实体。@CedricMartin(2/2)它与您的Java示例没有太大的不同,并且与我对抽象的解释非常一致,抽象是软件中的一个一般概念,Java通过封装实现,类层次结构和接口。主要的区别是在
spec
中没有绑定到组件的类型,而在Java中
Car
构造函数必须接受类型为Tire.oooh的对象。非常感谢您的回答,我不知道我引用的汽车示例是您的:)