编写另一种方法或向现有方法添加一个参数哪个更好?

时间:2018-08-08 19:52:00

标签: java model-view-controller methods controller

我有一个方法:

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()。如果我编写了另一种方法,则将在控制器中检查空标签,如果没有,则检查条件将在实用程序中。 哪种方法更好?

此外,如何在相同的上下文中重载该方法?

3 个答案:

答案 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参数:

    1. utility.createQuestionWithTags("", new Project(), new User(), new Date(), new HashSet<Tag>())

    2. utility.createQuestionWithTags("", new Project(), new User(), new Date(), null)

    3. utility.createQuestionWithTags("", new Project(), new User(), new Date())

缺点

  • 过载有时会很棘手,令人困惑
  • 进行单元测试时,由于签名几乎相同,因此需要确定要测试哪种方法。

答案 2 :(得分:0)

说实话,考虑到一般的重载有多复杂(明智的JLS),我很难接受。所谓“硬”,是指功能接口和重载(甚至在此站点上搜索相关问题,以查看人们有时如何拉头发(包括我在内))。但这并不仅仅与lambda有关,某些人认为重载过于复杂且几乎不需要,请阅读this作为示例。

重命名这些方法所做的事情是完成任务的最简洁的方法(除非您想到了构建器模式)。