我有一个方法:
public Question createQuestion(String text, Project project, User createdUser, Date createdDate)
该方法被控制器用来创建问题。现在参数中没有标签。我想实现将标签添加到问题的功能。
要添加标签,我需要向其传递一个tagSet,当用户在创建问题时未向问题添加标签时,tagSet也可以为空。因此,在将其添加到问题对象之前,我应该再传递一个参数,然后放置一个if
条件还是应该编写一个单独的方法?
public Question createQuestionWithTags(String text, Project project, User createdUser, Date createdDate,Set<Tag> questionTagSet)
,它将调用createQuestion
,然后在上述questionTagSet
方法返回的对象中设置createQuestion()
。如果我编写了另一种方法,则将在控制器中检查空标签,如果没有,则检查条件将在实用程序中。
哪种方法更好?
此外,如何在相同的上下文中重载该方法?
答案 0 :(得分:1)
这是Builder Pattern的理想候选人。在where
中声明一个构建器,使用Fluent Interface Pattern设置参数,最后调用Question
实例化适当构造的具体build()
实例。看起来像这样:
Question
需要指定一组标签的事件将在调用Question.builder().withText(text).withProject(project).build();
之前为上述代码提供后缀withTags(tags)
。
答案 1 :(得分:0)
这个问题可能有很多很好的答案,并且取决于您的特定用例,请牢记设计模式(有时反模式是合理的),最佳实践等,这将使您的代码更好。 / p>
也就是说,Question
应该具有添加新标签的方法,因为它是具有 tags
属性的类(不是吗?)。实施方式取决于您。可能是这样的:
public class Question {
// ...
public void addTags(Set<Tag> questionTagSet) {
this.tags.addAll(questionTagSet);
//...
}
}
这样,无论您在何处拥有Question
类型的对象,都可以像这样添加标签:
//...
Set<Tag> tags = new HashSet<>();
Question q = new Question();
q.addTags(tags);
//...
从这一点来看,我认为没有“最佳”选项,而是“针对您的用例的最佳选择”。因此,一个选项将是重载(请参见下面的方法重载以获取详细说明),另一个是一种新方法(当然具有不同的签名)。
方法重载:一种方法可以接收所有参数,而另一种方法可以接收除questionTagSet
之外的所有参数,在这种方法中,您仅通过提供默认值来调用接收所有参数的方法: null
。现在,在接收questionTagSet
参数的方法中,如果Question#addTags
参数不是questionTagSet
,则将调用null
方法。这将允许您使用相同的方法签名,但控制器使用不同的参数。因此,您不必在每个控制器中进行检查(这可能很多),因为您将检查仅移至一个位置:createQuestionWithTags
方法。
类似这样的东西:
方法,除questionTagSet
public Question createQuestionWithTags(String text, Project project, User createdUser, Date createdDate) {
return createQuestionWithTags(text, project, createdUser, createdDate, null);
}
包含所有参数的方法
public Question createQuestionWithTags(String text, Project project, User createdUser, Date createdDate,Set<Tag> questionTagSet) {
Question q = new Question();
//... some more additional logic here
if (questionTagSet != null) { //<- logic for adding tags moved here
q.addTags(questionTagSet);
}
return q;
}
如果您想对questionTagSet
参数做一些检查,则此实现可能会有所不同。
您可以以不同的方式从不同的控制器调用方法createQuestionWithTags
,而不必担心questionTagSet
参数:
utility.createQuestionWithTags("", new Project(), new User(), new Date(), new HashSet<Tag>())
utility.createQuestionWithTags("", new Project(), new User(), new Date(), null)
utility.createQuestionWithTags("", new Project(), new User(), new Date())
答案 2 :(得分:0)
说实话,考虑到一般的重载有多复杂(明智的JLS
),我很难接受。所谓“硬”,是指功能接口和重载(甚至在此站点上搜索相关问题,以查看人们有时如何拉头发(包括我在内))。但这并不仅仅与lambda有关,某些人认为重载过于复杂且几乎不需要,请阅读this作为示例。
重命名这些方法所做的事情是完成任务的最简洁的方法(除非您想到了构建器模式)。