質問

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:

Other suggestions I got:

  • original PR proposition: withAddedXXX
  • another proposition: withAdditionalXXX
役に立ちましたか?

解決

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
    }
}

他のヒント

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 */

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top