Reputation: 600
I have a method:
public Question createQuestion(String text, Project project, User createdUser, Date createdDate)
this method is being used to create a question by the controller. Now there is no tag here in the parameters. I want to implement a functionality to add tags to a question.
To add tag I need to pass it a tagSet which can be empty as well when the user does not add tag to a question while creating the question. So, should I pass one more parameter to it and then put an if
condition before adding that to the question object or should I write a separate method?
public Question createQuestionWithTags(String text, Project project, User createdUser, Date createdDate,Set<Tag> questionTagSet)
which will call the createQuestion
and then will set the questionTagSet
in the object returned by the above createQuestion()
method. If I write another method then check for the empty tag will be done in the controller and if not then that check condition will be in the utility.
Which approach is better?
Also, how about overloading the method in the same context?
Upvotes: 4
Views: 1530
Reputation: 14978
There can be a lot of good answers to this question and, depending of your specific use case, keep in mind design patterns (and that sometimes antipatterns are justified), best practices, etc, that will make your code better.
That said, Question
should have the method for adding new tags since it is the class which has the tags
attribute (isn't it?). The way you implement it is up to you. It could be something like:
public class Question {
// ...
public void addTags(Set<Tag> questionTagSet) {
this.tags.addAll(questionTagSet);
//...
}
}
This way wherever you have an object of type Question
you can add tags like this:
//...
Set<Tag> tags = new HashSet<>();
Question q = new Question();
q.addTags(tags);
//...
From this point, I think there is no "best" option, but "best option for your use case". So one option would be an overloading (see Method overload below for a detailed explanation) and the other one a new method (with a different signature of course).
Method overload: One method which receives all arguments and other which receives all arguments but questionTagSet
, in that one you only call the one which receives all arguments by providing a default value: null
. Now, in the method which receives the questionTagSet
argument you will call the Question#addTags
method if the questionTagSet
argument is not null
. This will allow you to use the same method signature but with different arguments from the controllers. Thus you don't have to do the checking in every controller (which could be a lot), since you moved the check to only one place: the createQuestionWithTags
method.
Something like this:
method with all arguments but questionTagSet
public Question createQuestionWithTags(String text, Project project, User createdUser, Date createdDate) {
return createQuestionWithTags(text, project, createdUser, createdDate, null);
}
method with all arguments
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;
}
This implementation can differ if you wan to do some checks with the questionTagSet
argument.
You can call the method createQuestionWithTags
from different controllers in different way without worrying about the questionTagSet
param:
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())
Upvotes: 0
Reputation: 120978
Well to be honest, taking into consideration of how complicated overloading is in general (JLS
wise), I have a hard time saying yes to it. And by hard I mean look at functional interfaces and overloading (or even search this site for related questions to see how people are pulling their hair sometimes - me included). But this is not related to lambdas only, overloading is by some people seen as too complicated and rarely needed, read this for one example.
What you have done with renaming those methods is the cleanest possible ways of achieving the task you have (unless you think of a builder pattern may be).
Upvotes: 0
Reputation: 147
This is an ideal candidate for the Builder Pattern. Declare a builder within Question
, setting the parameters using the Fluent Interface Pattern, calling build()
at the end to instantiate the appropriately-constructed, concrete Question
instance. It would look something like:
Question.builder().withText(text).withProject(project).build();
Occurrences that require a set of tags to be specified would supply suffix the above code with a call to withTags(tags)
prior to invoking build()
.
Upvotes: 1