Les systèmes de types statiques ont tous pour objectif de prévenir les utilisations incorrectes des données.
Il existe des exemples évidents de types faisant cela:
- vous ne pouvez pas obtenir le mois d'un UUID
- vous ne pouvez pas multiplier deux chaînes.
Il y a des exemples plus subtils
- vous ne pouvez pas payer pour quelque chose en utilisant la longueur du bureau
- vous ne pouvez pas faire de requête HTTP en utilisant le nom de quelqu'un comme URL.
Nous pouvons être tentés d’utiliser double
à la fois le prix et la longueur, ou d’utiliser un string
pour un nom et une URL. Mais cela compromet notre génial système de caractères et permet à ces utilisations abusives de passer les contrôles statiques du langage.
Obtenir une livre-seconde confondue avec Newton-seconde peut avoir des résultats médiocres au moment de l'exécution .
Ceci est particulièrement un problème avec les chaînes. Ils deviennent souvent le "type de données universel".
Nous sommes habitués principalement aux interfaces de texte avec des ordinateurs, et nous étendons souvent ces interfaces utilisateur (IU) aux interfaces de programmation (API). Nous pensons à 34.25 comme aux personnages 34.25 . Nous pensons à une date comme les personnages 05-03-2015 . Nous pensons à un UUID comme les caractères 75e945ee-f1e9-11e4-b9b2-1697f925ec7b .
Mais ce modèle mental nuit à l'abstraction des API.
Les mots ou la langue, qu'ils soient écrits ou parlés, ne semblent jouer aucun rôle dans mon mécanisme de pensée.
Albert Einstein
De même, les représentations textuelles ne doivent jouer aucun rôle dans la conception des types et des API. Attention le string
! (et autres types "primitifs" trop génériques)
Les types communiquent "quelles opérations ont un sens".
Par exemple, j'ai déjà travaillé sur un client pour une API HTTP REST. REST, correctement fait, utilise des entités hypermédia, qui ont des hyperliens pointant vers des entités apparentées. Dans ce client, non seulement les entités tapées (par exemple, utilisateur, compte, abonnement), les liens vers ces entités ont également été tapés (UserLink, AccountLink, SubscriptionLink). Les liens n'étaient guère plus que des wrappers Uri
, mais les types distincts rendaient impossible l'utilisation d'un AccountLink pour récupérer un utilisateur. Si tout avait été simple Uri
ou pire, string
ces erreurs n’auraient été constatées qu’au moment de l’exécution.
De même, dans votre cas, vous disposez de données utilisées dans un seul but: identifier un fichier Operation
. Il ne devrait pas être utilisé pour autre chose, et nous ne devrions pas essayer d'identifier les Operation
s avec des chaînes aléatoires que nous avons inventées. La création d'une classe séparée ajoute la lisibilité et la sécurité à votre code.
Bien sûr, toutes les bonnes choses peuvent être utilisées à l'excès. Considérer
combien de clarté cela ajoute à votre code
combien de fois il est utilisé
Si un "type" de données (au sens abstrait) est utilisé fréquemment, à des fins distinctes et entre interfaces de code, il constitue un très bon candidat pour être une classe séparée, aux dépens de la verbosité.