【问题标题】:How to not conflate a spec'ed map's key set and value set?如何不将指定地图的键集和值集混为一谈?
【发布时间】:2017-06-27 23:46:48
【问题描述】:

Clojure 官方规范文档指出:

大多数用于指定结构的系统都将 键集(例如地图中的键,对象中的字段)与 这些键指定的值的规范。 IE。在这样的 接近地图的模式可能会说:a-key's type is x-type and :b-key 的类型是 y-type。这是僵硬的主要来源 冗余。

在这个 SO 问题中: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 个元素。您也不能定义后轮是螺旋桨的浮动汽车。

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

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

【问题讨论】:

    标签: clojure specifications


    【解决方案1】:

    请稍等片刻,将软件开发视为一种实践。我们将在底部进行规范。

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

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

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

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

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

    现在应该清楚与规范的比较:

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

    【讨论】:

    • 感谢您的详细回答,但我真的不明白。这个例子不是我的:这个 car 例子来自另一个 SO question 的答案。 car 示例是否将 car 实体的定义与其 tires 组件的定义混为一谈?这与构造函数将采用 Tires 实例的 Java Car 类有何不同?
    • @CedricMartin (1/2) 是的,汽车的例子是我的,我承认它可能会更好。但是,这样想:如果我们想改变 tires 组件的任何细节,car 实体的定义会改变吗?不。所以,这两者是完全解耦的,以至于组件的规范甚至不需要存在来规范实体。
    • @CedricMartin (2/2) 这与您的 Java 示例没有不同,并且非常符合我将抽象作为软件中的一般概念的解释,即Java 通过封装、类层次结构和接口来完成。主要区别在于spec 中没有type 绑定到组件,而在Java 中Car 构造函数必须采用Tire 类型的对象。跨度>
    • 哦,明白了。非常感谢您的回答,我没有意识到我引用的 car 示例是您的:)
    猜你喜欢
    • 2023-03-31
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多