Here is a CodeSmell beginning programmers often write:
name1 = "Donald" name2 = "J." name3 = "Key"It's almost always cleaner to phrase that as one array with three values:
name[1] = "Donald" name[2] = "J." name[3] = "Key"...or even syntactic shortcuts like:
name = [ "Donald", "J.", "Key" ]This simplifies looping, passing, etc.
This is especially bad in languages where you can form variable names at runtime. Everything is OK until you want to know just how many / what variables there were...
Another variation of the same theme:
int x[NUMOBJECTS]; int y[NUMOBJECTS]; enum state st[NUMOBJECTS];... and so on. It is almost always better to use arrays of records instead of records of arrays, and especially instead of separate arrays.
Now, here's a smell you'll see unheeded by experienced programmers, because a bit subtler:
firstName = "Donald" middleName = "J." lastName = "Key"...instead of using an associative array:
name = { "first" => "Donald", "middle" => "J.", "last" => "Key", }In the case above, we're dealing with three String objects (or Name objects, if you want to be abstract about it). However, you can generalize: Any time you have a cluster of two or more objects of the same type, consider putting them into an associative array.
Of course, assoc. arrays are a poor man's object, so watch out for the "Wish I was an Object" smell.
Depends on which language you program in. In most statically typed languages, associative arrays have nary anything to do with objects, but records are the poor man's objects. In functional languages, on the other hand, building interfaces is often seen as a burden hindering rapid development. Functional languages tend to favor extensibility in the dimension of functionality, not in the dimension of alternate implementations.
Just remember: Parallel Things come from Duplication. And Duplication? It comes from the Devil.
Disagree
Putting things into an array and having to associate a position with meaning reduces clarity. It is simply much more complex to create an array and enum some indices than to declare individual variables. Using individual variables also simplifies extending the set of variables. I also think that the business rules will have more clarity in the form of "firstName" rather than name[First]. There is really no advantage in defining a sequence where one may not naturally exist (for example "lastName, firstName middleName" versus "firstName lastName"). For short, fixed size variable sets, I find it is almost always better to use discrete variables rather than an array.
Some of Sun's programmers seem very fond of this, there are several Java APIs that take tuples of arrays where one might expect arrays of tuples.
In Java arrays of tuples need more memory than tuples of arrays of primitive types, since every object needs a memory management overhead.
While that's true, I wonder if it's the reason. One example I have in mind involves a String[] and an Image[] to populate a list of "strings with images". I wonder if the memory overhead argument is conclusive in this case. If that is the reason, it would be nice to see the argument given in the Javadoc.
It's probably because there is no easy way in Java to define tuples. You can define array instances that contain multiple elements of the same type, but there is no way equivalent to C's inline definition of structs.
E.g. multiple strings and multiple images can be defined:
String[] strings = { "string1", "string2" }; Image images = { image1, image2 };But this is a syntax error
SomeType images_and_strings = { {"string1", image1}, {"string2", image2} };The nearest you can get is to define a utility class which is much more verbose:
public class NamedImage { public final String string; public final Image image; public NamedImage( String string, Image image ) { this.string = string; this.image = image; } } NamedImage[] images = new NamedImage[] { new NamedImage( "string1", image1 ), new NamedImage( "string2", image2 ) };In this case, you can do away with types and just declare an array of Objects. Then you can put into it anything but primitives, even other arrays. Or use java.util.List / java.util.Map (verbose syntax, though).