Java 使用fluent样式向不可变对象添加项的命名方法
是否有一种最佳实践或普遍接受的模式来命名方法,该方法使用fluent样式为JavaAPI“添加”到不可变对象的集合中 下面是一个代码示例:Java 使用fluent样式向不可变对象添加项的命名方法,java,immutability,fluent,Java,Immutability,Fluent,是否有一种最佳实践或普遍接受的模式来命名方法,该方法使用fluent样式为JavaAPI“添加”到不可变对象的集合中 下面是一个代码示例: 公共类GiveNuidGenerator{ 私有最终不可变列表playbackUUIDs; public-giveNuidGenerator(列出播放UUID){ this.playbackUUIDs=ImmutableList.copyOf(playbackUUIDs); } public-giveNudgeGenerator如何命名此方法(字符串uuid
公共类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)
vsString 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可能会得到更清晰的结果。我没有足够的声誉来支持您的答案,对不起,您关于注释的建议很有帮助,谢谢。