web-dev-qa-db-fra.com

Quel est le nom d'une fonction qui ne prend aucun argument et ne renvoie rien?

Dans le package Java 8 Java.util.function De Java, nous avons:

  • Fonction : prend un argument, produit un résultat.
  • Consommateur : prend un argument, ne produit rien.
  • Fournisseur : ne prend aucun argument, produit un résultat.
  • ... : Autres cas manipulant des primitives, 2 arguments, etc ...

Mais je dois gérer le cas " ne prend aucun argument, ne produit rien ".

Il n'y a rien pour cela dans Java.util.functionnal.

Donc, la question est:

Quel est le nom de ' une fonction qui ne prend aucun argument et ne renvoie rien'?

Dans Java 8, sa définition serait:

@FunctionalInterface
public interface InsertANameHere {
    void execute();
}

Executor existe déjà et a un autre but: " Un objet qui exécute les tâches Runnable soumises". La signature ne correspond pas à (execute(Runnable):void) et n'est même pas une interface fonctionnelle .

Runnable existe, mais il est fortement lié au contexte de thread:

  • Le package est Java.lang, Pas Java.util.function.
  • Le javadoc déclare: " L'interface Runnable doit être implémentée par n'importe quelle classe dont les instances sont destinées à être exécutées par un thread".
  • Le nom "Runnable" suggère un code en cours d'exécution dans un thread.
87
superbob

Le choix de Java de le faire de cette façon avec un nom distinct pour chaque arité ne valait pas vraiment la peine d'être imité. Cependant, si vous devez pour des raisons de cohérence, ou si vous écrivez du code de bibliothèque très générique, les suggestions de Konrad sont bonnes. Je pourrais jeter Procedure dans le ring.

L'utilisation d'un paradigme pseudo-fonctionnel ne signifie pas que les principes de dénomination normaux doivent sortir de la fenêtre. Les interfaces devraient presque toujours être nommées d'après ce qu'elles font, pas d'après une idée syntaxique générique. Si les fonctions sont placées dans une pile d'annulation, elles doivent être nommées UndoFunction. S'ils sont appelés à partir d'événements GUI, ils doivent être nommés GUIEventHandler.

74
Karl Bielefeldt

Dans le monde Java, il s'appelle Runnable. Dans le monde C #, il s'appelle Action.

Mais, il y a un meilleur nom qui s'intègre bien dans une vision plus large des choses.

La vue d'ensemble des choses vient plus tard, lorsque vous décidez qu'en plus de votre interface fonctionnelle vide sans paramètre, vous devez également avoir des interfaces fonctionnelles similaires qui acceptent un, deux ou plusieurs arguments, ou qui renvoient une valeur. Lorsque cela se produit, vous souhaiterez que les noms de toutes ces entités soient isomorphes et correspondent les uns aux autres.

Donc, en Java, j'ai mon propre ensemble d'interfaces fonctionnelles que j'appelle Procedures, défini comme suit:

public interface Procedure
{
    void invoke();
}

public interface Procedure1<T1>
{
    void invoke( T1 argument1 );
}

... (vous obtenez l'image.)

Et j'ai également un ensemble similaire d'interfaces appelé Functions, défini de manière similaire, avec le premier paramètre générique étant le type de retour:

public interface Function<R>
{
    R invoke();
}

public interface Function1<R,T1>
{
    R invoke( T1 argument1 );
}

Donc, mon point ici est que Procedure est un très bon nom car il s'intègre bien dans une vue plus large des choses. Si vous décidez ultérieurement d'avoir des interfaces fonctionnelles similaires avec des méthodes qui acceptent des arguments ou renvoient une valeur, vous l'exécuterez.

REMARQUE: En gros je suis d'accord = avec l'affirmation de Karl Bielefeldt selon laquelle "les principes de dénomination normaux ne devraient pas [sortir] de la fenêtre" et que "les interfaces devraient presque toujours être nommées d'après ce qu'elles font, pas d'après une idée syntaxique générique." Mais notez que même lui permet "presque toujours". Parfois, il y a un besoin de procédures et de fonctions (essentiellement anonymes), et c'est ce que le PO demande, et c'est ce à quoi je réponds.

Amendement 2017-11-10:

Vous pourriez vous demander pourquoi Function1<R,T1> Au lieu de Function1<T1,R>? Cela pourrait aller dans les deux sens, mais j'ai une préférence pour les valeurs de retour sur la gauche parce que j'aime suivre la convention de dénomination 'convert-from' (destination-from-source) par opposition à la 'convert-to' (source-to -destination) convention. (Ce qui est plus un accident qu'une convention, vraiment, dans le sens où très probablement, personne n'y a jamais pensé, car s'ils y avaient pensé, ils seraient arrivés à la convention de conversion. )

J'ai lu à ce sujet dans Joel Spolksy - Rendre le mauvais code faux , c'est un très long article, que je recommande de lire dans son intégralité, mais si vous voulez passer directement à l'affaire en question, recherchez pour 'TypeFromType', mais pour vous donner le TL; DR, l'idée est que myint = intFromStr( mystr ) est bien meilleur que myint = strToInt( mystr ), car dans le premier cas les noms des types sont proches de les valeurs associées, de sorte que vous pouvez facilement voir que "int" correspond à "int" et que "str" correspond à "str".

Donc, par extension, j'ai tendance à ordonner les choses de la façon dont elles vont apparaître dans le code.

34
Mike Nakis

Pourquoi pas Command? Étant donné qu'il ne prend aucune donnée et ne renvoie aucune donnée, mais en supposant que l'appeler provoque un certain effet (sinon ce serait vraiment inutile), j'imagine que c'est à peu près la seule chose qu'il peut faire - déclencher une action, faire bouger les choses.

En parlant de cela, il y a aussi un délégué générique Action dans .NET. Contrairement à Consumer de Java, il peut prendre de 0 à 16 arguments; en d'autres termes, la version la plus simple n'en prend aucune - voir MSDN .

Et puisque le nom n'implique pas qu'il y ait quoi que ce soit à "consommer", il semble également être un bon choix de nom.

18
Konrad Morawski