Java 使用fluent样式向不可变对象添加项的命名方法

Java 使用fluent样式向不可变对象添加项的命名方法,java,immutability,fluent,Java,Immutability,Fluent,是否有一种最佳实践或普遍接受的模式来命名方法,该方法使用fluent样式为JavaAPI“添加”到不可变对象的集合中 下面是一个代码示例: 公共类GiveNuidGenerator{ 私有最终不可变列表playbackUUIDs; public-giveNuidGenerator(列出播放UUID){ this.playbackUUIDs=ImmutableList.copyOf(playbackUUIDs); } public-giveNudgeGenerator如何命名此方法(字符串uuid

是否有一种最佳实践或普遍接受的模式来命名方法,该方法使用fluent样式为JavaAPI“添加”到不可变对象的集合中

下面是一个代码示例:

公共类GiveNuidGenerator{
私有最终不可变列表playbackUUIDs;
public-giveNuidGenerator(列出播放UUID){
this.playbackUUIDs=ImmutableList.copyOf(playbackUUIDs);
}
public-giveNudgeGenerator如何命名此方法(字符串uuid){
返回新的GiveNuidGenerator(ImmutableList.builder().addAll(playbackUUIDs.add(uuid.build());
}
}
这来自于我正在开发的一个项目,我们已经讨论了这个方法的最佳命名选项,但同时使用法语无助于选择一个好的名称

我试图寻找现有技术或最佳实践,以下是我迄今为止的发现:

  • 简单地使用
    将订单行添加到订单中,但我不知道这么通用(不命名我们正在添加的内容)是否是一个好的选择
  • 使用
    addXXX
    ,但它是
  • 使用newxxx的
    约定,但行为不同,它实际上是创建一个项目实例,而不是添加一个现有实例
我得到的其他建议:

  • 原始公关主张:
    withAddedXXX
  • 另一个命题:
    withAdditionalXXX

    • 我建议
      ,不要修改原始列表。因此,您可以有如下内容:

      GivenUUIDGenerator.with(originalList).and(a).and(b).and(c).generate();
      
      这是该类的外观:

      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
          }
      }
      
      公共类GiveNuidGenerator{
      具有(列表播放UUID)的公共静态GiveNudgeGenerator{
      返回新的givenuidgegenerator(playbackUUIDs);
      }
      私有最终不可变列表playbackUUIDs;
      私有GiveNuidGenerator(列出PlaybackUUID){
      this.playbackUUIDs=ImmutableList.copyOf(playbackUUIDs);
      }
      public-giveNuidGenerator和(字符串uuid){
      返回新的GiveNuidGenerator(ImmutableList.builder().addAll(playbackUUIDs.add(uuid.build());
      }
      公共…生成(){
      //…在这里做任何你想做的事情
      }
      }
      
      我认为将动词
      add
      append
      放在方法名称的开头是很好的选择。我不喜欢
      with
      ,因为它传递的信息不如
      add
      append
      那么多。我的intro CS教授总是强调,我们在开始时用动词命名方法名称,这是一个快速提示,让人们理解它是一个方法(例如,不是一个变量)


      大多数看到
      String
      类型的人也应该知道String是不可变的,所以应该没问题。但是,如果他们不这样做,您可能会想对它进行注释,并在Javadoc中添加注释,并在此处插入注释*/

      附加
      ,这是一个不错的选择,尽管有反例。例如,Java是可变的,它定义了几个
      append
      方法来改变实例

      流行的日期和时间库在它的一些不可变类(例如)中使用
      with
      ,其中该方法返回一个修改了某些字段的副本。虽然我相信也有反例

      您可能希望使用注释来代替命名约定,或者使用命名约定。JSR305(尽管已经失效)为此用例定义了一些注释。您可以使用
      @Immutable
      注释
      givenuidgegenerator
      ,使用
      @CheckReturnValue
      注释
      append
      /

      @Immutable
      记录实例创建后无法修改的文档


      @CheckReturnValue
      更微妙,它记录了一个方法没有副作用,因此如果你调用它而没有将结果分配给某个东西,你可能会误解它的工作原理。例如,
      myString.substring(5)
      vs
      String result=myString.substring(5)
      ,在这里创建了一个新的String实例并立即丢弃,myString
      没有任何变化。FindBugs可以检测到这一点,并在发生错误时标记错误。有关这方面的更多信息。

      我建议在此使用“append(…)”。一般来说,方法名称应该反映其功能。考虑到不同语言描述事物的差异,这个问题似乎相当主观。我想知道我的问题是否太主观了,这就是为什么我试图询问最佳实践/现有技术/命名约定。很像Java中广泛接受的getter/setter惯例,我想问的是,这个案例是否也有类似的情况。最后,提供的答案和这里封闭式问题的答案对我很有帮助:-虽然不是一个明确的好答案,但我想我的问题太主观了,很抱歉。对于像API这样的构建器来说,这很好,但是在这里我需要在现有的基础上构建一个新的
      GivenUidGenerator
      。@XavierHanin我已经编辑了我的文章,添加了一个我的意思的示例。好吧,我更好地理解了,我把
      generate
      方法与构建器方法混淆了。我非常喜欢您所展示的
      ,但是当调用从其他地方获取的对象(例如参数)时,它的表达性就差了。
      void doSgWith(givenuidgegenerator generator){generator.and(a.generate();}
      是否清晰?@XavierHanin否,但这是大多数流畅API的固有缺陷。它们应该作为一个整体使用。如果您想将部分内容转移到其他方法,使用非流畅的API可能会得到更清晰的结果。我没有足够的声誉来支持您的答案,对不起,您关于注释的建议很有帮助,谢谢。