49 votes

Où mettre les spécifications pour Clojure.Spec?

Donc, je suis plongée plus profonde et plus profonde en Clojure.Spec.

Une chose que je suis tombé sur est, où mettre mes spécifications. Je vois trois options:

Mondial Dans Le Fichier De Spécification

Dans la plupart des exemples, j'ai trouvé en ligne, il y a un gros spec.clj le fichier, qui est requis dans l'espace principal. Il a tout l' (s/def) et (s/fdef) pour tous les "types de données" et les fonctions.

Pro:

  • Un fichier pour les gouverner tous

Contra:

  • Ce fichier peut être d'un grand
  • Seul Responsibliy Principe violé?

Spécifications de la production d'espaces de noms

Vous pourriez mettre votre (s/def) et (s/fdef) droite à côté de votre code de production. De sorte que, la mise en œuvre et le spec co-exister dans le même espace de noms.

Pro:

  • la co-localisation de la mise en œuvre et spec
  • un espace de noms est un sujet de préoccupation?

Contra:

  • le code de production pourrait être gênant
  • un espace de deux préoccupations?

Dédié spec de la structure de l'espace de noms

Puis j'ai pensé, peut-être que les Specs sont un troisième type de code (à côté de la production et de test). Alors peut-être qu'ils méritent leur propre structure d'espaces de noms, comme ceci:

├─ src
│  └─ package
│     ├─ a.clj
│     └─ b.clj
├─ test
│  └─ package
│     ├─ a_test.clj
│     └─ b_test.clj
└─ spec
   └─ package
      ├─ a_spec.clj
      └─ b_spec.clj

Pro:

  • dédié (mais relative) des espaces pour les specs

Contra:

  • vous avez à la source et exigent la bonne espaces de noms

Qui a de l'expérience avec l'une des approches?
Est-il une autre option?
Que pensez-vous des différentes options?

22voto

levand Points 4020

J'ai l'habitude de mettre les données dans leur propre espace de noms, aux côtés de l'espace de noms qu'ils décrivent. Il n'est pas particulièrement question de ce qu'ils sont nommés, aussi longtemps qu'ils utilisent certaines conventions de nommage. Par exemple, si mon code est en my.app.foo, je vais mettre les specs en my.app.foo.specs.

Il est préférable pour les spec clé de noms dans l'espace de noms du code, toutefois, pas l'espace de noms de la spécification. C'est toujours facile à faire en utilisant un espace de noms d'alias sur le mot clé:

(ns my.app.foo.specs
  (:require [my.app.foo :as f]))

(s/def ::f/name string?)

Je voudrais rester à l'écart d'essayer de tout mettre dans un grand spec espace de noms (ce qu'est un cauchemar.) Alors que je ne pouvais les mettre juste à côté de l'spec'd code dans le même fichier, ce qui nuit à la lisibilité de l'OMI.

Vous pourriez mettre tous vos spec espaces de noms dans un autre chemin de la source, mais il n'y a pas de réel avantage à le faire, sauf si vous êtes dans une situation où vous voulez distribuer le code, mais pas les specs, ou vice-versa... difficile d'imaginer ce que ce serait bien.

14voto

MasterMastic Points 3868

À mon avis, les spécifications doivent être dans les mêmes ns que le code.

Ma réflexion est ma philosophie personnelle, et techniquement, il fonctionne bien. Ma philosophie est que la spécification d'une fonction est une partie intégrante de la partie. Ce n'est pas une petite chose. C'est certainement pas "deux préoccupations" que de mettre dans l'OP. En fait, c'est que la fonction est, car, en termes d'exactitude: qui se soucie de la mise en œuvre? qui se soucie de ce que vous avez écrit dans votre defn? qui se soucie de l'identifiant? qui se soucie de rien , mais la spec?
Je pense que c'est bizarre, parce que non seulement clojure.spec est venu plus tard, aussi la plupart des langues ne vous laissera pas avoir des specs comme une partie intégrante de chose, même si vous voulais que ce soit, et de quelque chose d'approchant (tests dans le code, peut-être) est généralement mal vu, alors, évidemment, ça fait bizarre. Mais lui donner une certaine pensée, et vous pourriez arriver à une conclusion comme je l'ai fait (ou vous ne pouvez pas, cette partie est d'opinions).

La seule bonne des raisons que je pense à pourquoi vous ne voulez pas les specs de la même ns sont ces deux raisons:

  1. Il encombre votre code.
  2. Vous souhaitez soutenir Clojure versions pré Clojure 1.9.0.

Comme pour la première raison, et bien, encore une fois, je pense que c'est une partie intégrante de vos fonctions. Si vous trouvez que c'est vraiment trop, mon conseil serait le même que si votre ns serait trop encombrée, indépendamment de spec: voyez si vous pouvez le séparer.

Quant à la seconde raison, si vous intéresse vraiment, vous pouvez vérifier dans le code si le clojure.spec ns est disponible, si ce n'est pas alors de l'ombre aux noms de fonctions/macros qui sont NOP. Une autre option est d'utiliser clojure-avenir-spec mais je n'ai pas essayé moi-même donc je ne sais pas comment cela fonctionne bien.

Une autre façon dont cela fonctionne bien techniquement, c'est que parfois il y a une dépendance cyclique que vous ne pouvez pas gérer avec des espaces de noms différents, par exemple lors de vos spécifications dépendent de votre code (pour la fonction de spécifications) et votre code dépend de vos spécifications techniques pour l'analyse (voir cette question).

7voto

Colin Points 65

Une autre considération en fonction de votre cas d'utilisation, les spécifications à côté de votre code principal, limite l'utilisation de votre code de Clojure 1.9 clients, ce qui peut ou peut ne pas être ce que vous voulez. Comme @levand, je vous recommande un parallèle espace de noms pour chacun de vos espaces de noms de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X