Nom de l'interface: préfixe «Can-» vs suffixe «-Able»


29

Il est courant d'utiliser '-able' comme suffixe pour les interfaces, par exemple

Serializable Printable Enumerable Drinkable Shootable Rotatable

Je pensais que «Can-» pourrait mieux parce qu'il pourrait être plus descriptif. Oui, il est plus verbeux et ajoute du bruit au nom de l'interface. En particulier, les verbes passifs peuvent être utilisés.

Par exemple, 1 Tirable signifie que l'objet est capable de tirer (une arme à feu pourrait implémenter cela), ou cela signifie-t-il qu'il peut être tiré (une planche cible pourrait implémenter cela). Avec le préfixe 'Can-', le premier serait "CanShoot" et le second serait "CanBeShotAt" ou "CanShootAt".

Par exemple: 2 Un document 'CanBePrinted' et une imprimante 'CanPrint'

Ou devrions-nous nous en tenir à «-Able» et laisser la documentation fournir le contexte?

Des opinions.


Man, utilisez "-able". Période.
Tulains Córdova

2
Utilisez les deux pourclass Cannibal implements Can, Able {}
Thomas Eding

Réponses:


18

Peut-être voulez-vous pouvoir?

Quelques exemples de .Net:

NetworkStream.Readable
NetworkStream.Writable
Stream.CanRead
Stream.CanWrite
Type.IsSerializable

Il ne semble pas y avoir de norme uniforme. Allez avec ce qui se lit bien.

if (document.IsPrintable && printer.CanPrint) { printer.Print(document) }

EDIT: Comme indiqué, la question concernait les interfaces, pas les propriétés.

Dans ce cas, je ne trouve aucune interface nommée Can-. Les interfaces ont tendance à toujours utiliser -able. Je serais d'accord avec cette terminologie. Une méthode peut demander comme paramètre a ISerializable objectou IPrintable document. Demander un ICanBeSerialized objectou un ICanBePrinted documentest très difficile à lire.

De l'autre côté, l'imprimante, je suggère simplement d'appeler l'interface IPrinter. Votre méthode demandera un IPrinter device.

Lisez à haute voix la signature de méthode ci-dessous. (Personnellement, je considère que le préfixe "I" est silencieux.) Est-ce que cela se lit bien? Est-ce que ça sonne bien?

void PrintDocument(IPrinter device, IPrintable document)
{
    device.Print(document)
}

2
Document.IsPrintable est meilleur que Document.CanBePrinted. Pour autant que je sache, ils utilisaient -able pour éviter la voix passive.
Thanos Papathanasiou

"Peut être imprimé" semble être un anglais plus approprié que "est imprimable".
Danny Varod

1
"La voix passive est utilisée lorsque l'accent est mis sur l'action. Cependant, il n'est pas important ou ne sait pas qui ou quoi exécute l'action." Je peux seulement deviner qu'ils voulaient que la concentration reste sur l'objet et non sur l'action. Donc, si un "Type.IsSerializable" lève une exception, c'est la faute du Type. pas les méthodes, mais si un "Type.CanBeSerialized" lève une exception, vous blâmeriez la méthode et non le type. Certes la différence est mineure mais elle est là.
Thanos Papathanasiou

3
Je vois que c'est la réponse acceptée, mais cela ne répond pas à la question du PO. Les exemples fournis sont des noms de propriété . L'OP demande une convention de nommage pour l' interface noms, tels que ISerializable, IDataErrorInfoet INotifyPropertyChanged.
Kevin McCormick

@KevinMcCormick, bon point! Modifications ci-dessus.
Hand-E-Food du

23

Grammaticalement parlant, "canFoobar" est un prédicat, tandis que "Foobarable" est un adjectif ou un nom (généralement un nom dans le contexte d'une API).

Notez également la différence subtile: -able implique un rôle passif au nom auquel il est appliqué, c'est-à-dire que si quelque chose est foobarable, alors il peut être foobaré par autre chose; can- implique un rôle actif, c'est-à-dire que si Something canFoobar, alors il peut foobar autre chose. Ou, sous un angle différent: si A peut foobar B, alors A.canFoobar()et B is Foobarable.

En termes d'expressivité OOP, j'associerais des prédicats à des méthodes ou des propriétés, tandis que les noms sont des classes ou des interfaces. Alors:

instance.canFoobar();

class Something implements Foobarable { ... }

7

Personnellement, je m'en tiendrai à la version -able. Voici ma raison: la plupart (tous?) Des éditeurs graphiques suggèrent des identifiants basés sur ce que vous avez tapé. Bien que certains d'entre eux soient suffisamment «intelligents» pour effectuer également des recherches dans les identifiants, certains ne proposent que des débuts de recherche d'identifiants.

Pour accélérer la saisie, vous souhaitez raccourcir la liste des identifiants suggérés avec le moins de touches possible. Plus les identifiants ont le même début, par exemple «ICan-», plus vous devrez taper de caractères.

Si vous pensez que ce n'est pas un problème dans votre cas, c'est parfait et je recommanderais d'utiliser d'autres critères pour choisir une convention de dénomination. Dans certains cas, par exemple dans notre équipe, nous préférons les identifiants qui distinguent le moins de frappes possible.

En dehors de cela, je recommanderais d'utiliser la convention de dénomination qui rend votre code le plus compréhensible pour ceux qui travaillent sur le projet. Ayez une conversation au sein de votre équipe. Il n'y a pas de bien ou de mal en tant que tel. Juste des conventions qui fonctionnent et des conventions qui fonctionnent moins.

N'oubliez pas que de bons outils de refactoring vous permettent de renommer les choses aussi souvent que vous le souhaitez. Il est donc facile d'expérimenter différentes approches.


1
+1. Mon raisonnement serait le même, mettez d'abord le verbe de contrôle pour faciliter la recherche / recherche / tri dans l'IDE.
pap

1
non seulement l'intellisense fonctionne de cette façon, mais il en va de même pour un texte de numérisation humain, les préfixes rendent votre code moins lisible
jk.

7

Il est clair que le préfixe et le suffixe sont des choix presque évidents pour différents types d'actions ou plutôt, différentes directions d'une action.

Cependant, l'utilisation et les préférences actuelles peuvent être incohérentes pour de nombreuses raisons.

L'action est exécutée par l'objet:
CanShoot -> Il tire quelque chose sur
CanFly -> Il vole
CanChange -> Il change

L'action est effectuée sur l'objet:
Lisible -> Vous pouvez le lire
Écrivable -> Vous pouvez l'écrire (sur)
Imprimable -> Vous pouvez l'imprimer

Bien que cela ne soit pas une règle ou même nécessairement logique, cela aide à adopter la convention et à maintenir la cohérence d'utilisation dans la dénomination des variables.


4

Je pense que vous voudrez peut-être faire la distinction entre la capacité et la permission. Même si un élément est susceptible d'être sérialisé Serializableet CanSerializeimplique qu'il existe également des problèmes d'autorisation (ou peut-être un manque d'espace disque) et que vous devrez peut-être prendre en compte MaySerialize. Laisser les choses en place ~ableélimine le besoin de distinguer entre canet may.


SerializableIfNotDiskFullAndIfNotPermissionMissing ... Lol :)
Max

2

Lorsque je sous-classe / implémente des interfaces, je pense que la règle générale est que vous devriez pouvoir dire "B est un A" (où B implémente A). Il ne semble pas juste de dire:

A Documentest unCanBePrinted

Mais cela semble juste (ou du moins mieux) de dire:

A Documentest unPrintable


2

Je pense que Xable au niveau grammatical et conventionnel est meilleur pour les noms d'interfaces, tandis que IsX, CanX, DoesX sont meilleurs pour les noms de propriétés.

Depuis MSDN:

"Nommez les propriétés booléennes avec une phrase affirmative (CanSeek au lieu de CantSeek). Vous pouvez également préfixer les propriétés booléennes avec Is, Can ou Has, mais uniquement là où cela ajoute de la valeur." http://msdn.microsoft.com/en-us/library/ms229012.aspx


+1 pour le lien utile; Je ne sais jamais comment nommer les choses
CamelBlues

0

À mon avis, la variante "-able" est beaucoup plus lisible que votre "CanDoSomething" proposé qui impose beaucoup plus de bosses de chameau.


1
et Can- est plus un nom de méthode
ratchet freak

Nom de la propriété - voir MSDN. Un nom de méthode doit être "verbes ou phrases verbales". D'ailleurs, qu'est-ce qui ne va pas avec plusieurs bosses?
Danny Varod

0

Dans Scala, *Ableest utilisé pour les interfaces, mais Can*est utilisé pour le modèle de classe de type. Essentiellement, pour pouvoir appeler certaines méthodes, une valeur implicite d'un certain type doit exister dans la portée. Le nom de ce type est parfois précédé du préfixe Can.


Can * n'est pas un bon nom pour une classe. Citation de MSDN: "Faites des classes de nom, des interfaces et des types de valeur avec des noms, des phrases nominales ou des expressions adjectives occasionnelles, en utilisant la casse Pascal", lien: msdn.microsoft.com/en-us/library/ms229040.aspx Bon nom pour la classe serait Document, le nom acceptable serait Imprimable.
Danny Varod

Un exemple dans la langue Scala est le CanBuildFrom. Ce serait une phrase adjectif. Le cas d'utilisation de cette classe est très différent de celui des autres classes. Les instances de cette classe ne sont presque jamais construites ni résolues par le client - elles sont plutôt disponibles dans la portée de certains types. S'ils sont disponibles pour un certain type, les méthodes impliquant ce type qui sont marquées pour nécessiter cette classe de types peuvent être appelées. Cela existe pour offrir un mécanisme d'extensibilité plus flexible que le sous-typage. Voir scala-lang.org/node/114 .
axel22

Je me souviens seulement d'avoir utilisé des expressions adjectives pour les classes simulées implémentant des interfaces pour les tests unitaires - car elles n'avaient pas de véritable rôle.
Danny Varod
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.