Reputation: 43
Is there a best practice or commonly accepted pattern to name methods that "adds" something to a collection on an immutable object with fluent style for Java API?
Here is a code example:
public class GivenUUIDGenerator {
private final ImmutableList<String> playbackUUIDs;
public GivenUUIDGenerator(List<String> playbackUUIDs) {
this.playbackUUIDs = ImmutableList.copyOf(playbackUUIDs);
}
public GivenUUIDGenerator howShouldINameThisMethod(String uuid){
return new GivenUUIDGenerator(ImmutableList.<String>builder().addAll(playbackUUIDs).add(uuid).build());
}
}
This is coming from a Pull Request on a project I'm developing, and we already had a discussion on the best naming option for this method, but being both french doesn't help to choose a good name.
I've tried to find prior art or best practices, here is what I've found so far:
with
to add order lines to an order, but I don't know if being that much generic (not naming what we are adding) is a good option.addXXX
but it's not immutable.withNewXXX
convention, but the behavior is different, it's actually creating an item instance, not adding an existing oneOther suggestions I got:
withAddedXXX
withAdditionalXXX
Upvotes: 2
Views: 644
Reputation: 129287
append
is an okay choice, although there are counter-examples. For instance, Java's StringBuilder is mutable, and defines several append
methods which mutate the instance.
The popular date and time library, JodaTime, uses with
in some of it's immutable classes (e.g. DateTime) where the method returns a copy with some fields modified. Though I'm sure there's counter-examples for that too.
Perhaps instead of, or as well as a naming convention, you may want to use annotations. The (albeit defunct) JSR 305 defined some annotations for this use case. You could annotate GivenUUIDGenerator
with @Immutable
and the method append
/with
with the annotation @CheckReturnValue
.
@Immutable
documents that the instance can't be modified once created.
@CheckReturnValue
is more subtle, it documents that a method has no side-effects, so if you call it without assigning the result to something, you probably misunderstand how it works. E.g. myString.substring(5)
vs String result = myString.substring(5)
, here a new instance of String is created and immediately discarded, nothing has changed about myString
. FindBugs can detect this and flag an error if it happens. Some more info on this useful blog post.
Upvotes: 0
Reputation: 6717
I would suggest and
, and not modify the original list. Therefore, you could have something like:
GivenUUIDGenerator.with(originalList).and(a).and(b).and(c).generate();
This is what the class would look like:
public class GivenUUIDGenerator {
public static GivenUUIDGenerator with(List<String> playbackUUIDs) {
return new GivenUUIDGenerator(playbackUUIDs);
}
private final ImmutableList<String> playbackUUIDs;
private GivenUUIDGenerator(List<String> playbackUUIDs) {
this.playbackUUIDs = ImmutableList.copyOf(playbackUUIDs);
}
public GivenUUIDGenerator and(String uuid){
return new GivenUUIDGenerator(ImmutableList.<String>builder().addAll(playbackUUIDs).add(uuid).build());
}
public ... generate() {
// ... do here whatever it is you want to do with your list
}
}
Upvotes: 2
Reputation: 19
I think putting the verb add
or append
at the beginning of the method name are good options. I'm not a fan of with
because it doesn't convey as much information as add
or append
. My intro CS professor always made it a point that we name our method names with a verb in the beginning as a quick cue for people to understand it's a method (and not a variable, for example).
Most people seeing a String
type should also know strings are immutable so you should be fine. But just in case they don't, you'd probably want to comment it and add that note in the Javadoc with /** insert comments here */
Upvotes: 0