The codebase where I work has an object called Pair where A and B are the types of the first and second values in the Pair. I find this object to be offensive, because it g
This is just prototype-quality code that likely was smashed together and has never been refactored. Not fixing it is just laziness.
The real use for tuples is for generic functionality that really doesn't care what the component parts are, but just operates at the tuple level.
It's code reuse. Rather than writing Yet Another Class With Exactly The Same Structure As The Last 5 Tuple-Like Classes We Made, you make... a Tuple class, and use that whenever you need a tuple.
If the only significance of the class is "to store a pair of values", then I'd say using tuples is an obvious idea. I'd say it was a code smell (as much as I hate the term) if you started implementing multiple identical classes just so that you could rename the two members.
If you're doing a Schwartzian transform to sort by a particular key (which is expensive to compute repeatedly), or something like that, a class seems to be a bit overkill:
val transformed = data map {x => (x.expensiveOperation, x)}
val sortedTransformed = transformed sort {(x, y) => x._1 < y._1}
val sorted = sortedTransformed map {case (_, x) => x}
Having a class DataAndKey
or whatever seems a bit superfluous here.
Your example was not a good example of a tuple, though, I agree.
Many things have already been mentioned, but I think one should also mention, that there are some programming styles, that differ from OOP and for those tuples are quite useful.
Functional programming languages like Haskell for example don't have classes at all.
Tuples are used all the time in Python where they are integrated into the language and very useful (they allow multiple return values for starters).
Sometimes, you really just need to pair things and creating a real, honest to god, class is overkill. One the other hand, using tuples when you should really be using a class is just as bad an idea as the reverse.
The code example has a few different smells:
There is already a tuple available in the framework; the KeyValuePair
structure. This is used by the Dictionary
class to store pairs, but you can use it anywhere it fits. (Not saying that it fits in this case...)
If you have a list of pairs it's better to use the KeyValuePair
structure than a class with the same purpose, as it results in less memory allocations.
A class with properties clearly shows what the values mean, while a Pair<int,int>
class doesn't tell you anything about what the values represent (only that they are probably related somehow). To make the code reasonably self explanatory with a list like that you would have to give the list a very desciptive name, like productIdAndQuantityPairs
...