45 votes

Pourquoi utiliser des tuples à la place des objets?

La base de code où je travail a un objet appelé Paire où A et B sont les types de la première et deuxième valeurs de la Paire. Je trouve cet objet d'être choquant, car il est utilisé à la place d'un objet clairement nommé les membres. Donc, je trouve ceci:

List<Pair<Integer, Integer>> productIds = blah();
// snip many lines and method calls

void doSomething(Pair<Integer, Integer> id) {
  Integer productId = id.first();
  Integer quantity = id.second();
}

Au lieu de

class ProductsOrdered {
  int productId;
  int quantityOrdered;
  // accessor methods, etc
}

List<ProductsOrderded> productsOrdered = blah();

De nombreuses autres utilisations de la Paire dans la base de code sont de même mauvaise odeur.

J'ai Googlé tuples et ils semblent être souvent mal compris ou utilisé dans des moyens douteux. Est-il un argument convaincant pour ou contre leur utilisation? Je peux comprendre ne voulant pas créer d'énormes hiérarchies de classe mais réaliste des bases de codes où la hiérarchie de classe allait exploser si les tuples n'ont pas été utilisés?

36voto

rlbond Points 24215

Tout d'abord, un tuple est rapide et facile: au lieu d'écrire une classe pour chaque fois que vous voulez mettre 2 choses ensemble, il y a un modèle qui le fait pour vous.

Deuxième de tous, ils sont génériques. Par exemple, en C++ std::map utilise un std::pair de la clé et la valeur. Ainsi, une paire peut être utilisé, au lieu d'avoir à faire une sorte de wrapper classe avec des méthodes accesseur pour chaque permutation de deux types.

Enfin, ils sont utiles pour retourner plusieurs valeurs. Il n'y a vraiment aucune raison de faire une classe spécifiquement pour une fonction de plusieurs valeurs de retour, et ils ne devraient pas être traités comme un seul objet, si elles sont sans rapport avec.

Pour être juste, le code que vous avez collé est une mauvaise utilisation d'une paire.

16voto

Aaron Maenpaa Points 39173

Les Tuples sont utilisés tout le temps en Python où ils sont intégrés dans la langue et très utile (ils permettent à plusieurs valeurs de retour pour les débutants).

Parfois, vous avez vraiment besoin juste de la paire de choses et la création d'un réel, honnête à dieu, la classe est exagéré. L'un de l'autre main, à l'aide de n-uplets lorsque vous devez vraiment être à l'aide d'une classe est une aussi mauvaise idée que l'inverse.

10voto

Guffa Points 308133

L'exemple de code a un peu différentes odeurs:

  • Réinventer la roue

Il y a déjà un tuple disponibles dans le cadre de l' KeyValuePair de la structure. Il est utilisé par l' Dictionary classe pour stocker des paires, mais vous pouvez l'utiliser partout où il va. (Pas de dire qu'il s'adapte dans ce cas...)

  • Faire une roue carrée

Si vous avez une liste de paires, il est préférable d'utiliser l' KeyValuePair de la structure de classe avec le même but, comme il en résulte moins de l'allocation mémoire.

  • Cacher l'intention

Une classe avec des propriétés montre clairement que les valeurs moyennes, tandis qu'un Pair<int,int> de la classe n'est pas tout vous dire sur ce que les valeurs représentent (seulement qu'ils sont probablement liés d'une certaine manière). Pour rendre le code raisonnablement explicites avec une liste comme ça vous auriez à donner la liste très desciptive nom, comme productIdAndQuantityPairs...

8voto

Juliet Points 40758

Pour ce que sa vaut le coup, le code de l'OP est un bordel pas parce qu'il utilise des n-uplets, mais parce que les valeurs du tuple sont trop faiblement typé. Comparer les suivantes:

List<Pair<Integer, Integer>> products_weak = blah1();
List<Pair<Product, Integer>> products_strong = blah2();

J'aimerais vous énervez pas trop si mon équipe de dev passaient autour Id plutôt que des instances de classe, car c'est un entier qui peuvent représenter quelque chose.


Avec cela étant dit, les tuples sont extrêmement utiles lorsque vous les utilisez à droite:

  • Les Tuples existe pas de groupe ad hoc de valeurs. Ils sont certainement mieux que la création d'un nombre excessif de classes wrapper.
  • Alternative utile pour sortir/ref paramètres lorsque vous avez besoin de retourner plus d'une valeur à partir d'une fonction.

Toutefois, les n-uplets en C# faire mes yeux de l'eau. De nombreux langages comme OCaml, Python, Haskell, F#, et donc sur une spéciale, concis syntaxe pour la définition des n-uplets. Par exemple, en F#, la Carte du module définit un constructeur comme suit:

val of_list : ('key * 'a) list -> Map<'key,'a>

Je peux créer une instance d'une carte à l'aide de:

(* val values : (int * string) list *)
let values = 
    [1, "US";
     2, "Canada";
     3, "UK";
     4, "Australia";
     5, "Slovenia"]

(* val dict : Map<int, string> *)
let dict = Map.of_list values

Le equilvalent code en C# est ridicuous:

var values = new Tuple<int, string>[] {
     new Tuple<int, string>(1, "US"),
     new Tuple<int, string>(2, "Canada"),
     new Tuple<int, string>(3, "UK"),
     new Tuple<int, string>(4, "Australia"),
     new Tuple<int, string>(5, "Slovenia")
     }

 var dict = new Dictionary<int, string>(values);

Je ne crois pas qu'il existe quelque chose de mal avec les tuples en principe, mais C#syntaxe est trop lourd pour obtenir le plus de profit.

5voto

jalf Points 142628

C'est la réutilisation du code. Plutôt que d'écrire Encore une Autre Classe Avec Exactement La Même Structure Que Les 5 Dernières Tuple des Classes Comme Nous l'avons Fait, vous allez faire... un n-uplet de classe, et l'utiliser chaque fois que vous avez besoin d'un tuple.

Si la seule signification de la classe est "pour stocker une paire de valeurs", alors je dirais aide de n-uplets est une idée évidente. Je dirais que c'était une odeur de code (autant que je déteste ce terme) si vous avez commencé à mettre en œuvre de multiples identiques classes de sorte que vous pouvez renommer les deux membres.

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