This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What's the best way to refactor a method that has too many (6+) parameters?
If a constructor has a long parameter list, should we consider it bad style and refactor it? If yes, how?
Consider using a Builder. Instead of having a constructor where some of the parameters can be null:
Foo foo = new Foo(name, id, description, path, bar);
And instead of telescoping constructors - i.e. making one constructor for each combination of parameters, you can have:
Foo foo = new FooBuilder().setName(name).setPath(path).build();
It may be an appropriate set of parameters, but a lot of the time my answer would be yes. Break the parameters into a logical subgroupings if they exist i.e. rather than creating a Car from many different parts, group some parts into an Engine object, some into a Chasis etc.
Alternatively, if some of those parameters are optional, make use of the builder pattern so that you only include them when necessary.
Ultimately, though, do whatever makes most sense for you and your domain.
Yes, you should. See What's the best way to refactor a method that has too many (6+) parameters?
Related
This question already has answers here:
How do I use optional parameters in Java?
(17 answers)
Closed 1 year ago.
I need to have method that accepts let say 3 input parametars.
Calculate_Salary(int ratio, int vocationDays, int travelDays)
Many of the people do not travel, and rearly use vocation days in that case I want to call the functions in the best way (let say like in C++ only with one parametar, and other two will have default values)
There are planty of way to implement it I know (call method with zero values, overload it, implement default valuses in the body of method ). And note. it is simple with ints, it is more complex with the objects.
Calculate_Salary (ratio)
Which is the safest and fastest soulution, and is there something "new" in Java that can make this happen easy?
Thanks
As far as I know there is no solution that makes it really easy. But overloading is by far the best implementation you can do, moreover it is really easy, therefore I would go with this.
Moreover you do not need to implement a whole new function, simply call the first method with the default parameters you want.
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?
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().
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).
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.
Pros of this:
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())
Cons
Overloading can be tricky and confusing sometimes
When doing unit test you need to be sure which method are you testing, since the signature is almost the same.
This question already has answers here:
Can I add new methods to the String class in Java?
(16 answers)
Closed 5 years ago.
I am trying to add custom function that operates on string variable like below in java (in my android project actually)
String name="tester";
name.isAlreadyEntered();
public static boolean isAlreadyEntered(String name){
return (checkInMyDb(name));
}
I am going to use this for some more functions. I know its a bit stupid question. I know this does exists in javascript & in .Net. As I am new to java I m not aware of its possibility. Forgive if I am asking wrongly. But if possible please help me on how to get this syntax
If you really intend to add a new method to java.lang.String.java then you are probably on a wrong path which will only cause pain and agony in future :d. Better stop, rethink redesign and refactor.
Anyways firstly NO you can not add a new method to String class. It is final and hence you can not and neither you should even intend to sub class it. If you intend to do so then its a poor design, which you must refactor.
If you just wish to check if some String is present in the database, you can simply declare the method which can accept a parameter of type String , check its presence in the database and return true if found else return false.
If above solution does not work for you then you can try takimg help of Composition. If you want a Object with such method (which can tell if the object is present in db) then You can create a class , may decide to name it as per your contextual needs , I am naming it as StringContainer. This class can have a instance variable of type String. Now instead of using String object you can use the object of this newly created custom class composing the object of String You can include a method to check if entry cossponding to an object of this class had been made in database or not.
This question already has answers here:
WITH statement in Java
(8 answers)
Closed 8 years ago.
In VB / VBA you can do something like this:
With person
.Name = "John"
.Age = 32
End With
But in java I can't figure out how or if that functionality exists. Everything I see seems to just repeat the object references, like this:
person.setName("John");
person.setAge("32");
If it doesn't exists, is there at least some methodology to cut down on the repetition?
If it doesn't exists, is there at least some methodology to cut down on the repetition?
Nope, not really - not unless you control the type.
If you do control the type, you can make the set methods return this, allowing you to chain the method calls. This is often useful for builder types:
Person person = Person.newBuilder().setName("John").setAge(32).build();
(You can just make your types mutable rather than separating builder types from immutable non-builder types, but I'm just a fan of immutability...)
This question already has answers here:
Best practice for passing many arguments to method?
(17 answers)
Closed 9 years ago.
I've read a recommendation in "Effective Java" to use the Builder pattern when faced with constructors that use lots of parameters.
Does the same pattern apply to methods with lots of parameters ?
Yes, sort of. You basically create a new type to encapsulate all the parameters - or maybe just some of them.
Now you can create a builder and then an immutable version of the type - or you could just allow the "uber-parameter" type to be mutable and pass it directly in. In the latter case you don't have a builder pattern as such, but you can sort of view it as building the method call itself, in that you can specify each aspect of the method call separately.
You could argue that the builder pattern is actually just a special case of this pattern, in some ways - it so happens that the build() method is usually on the builder rather than having the builder as a method parameter elsewhere, but there's a definite correlation between the way the two work.
An example of this in the .NET framework is XmlWriterSettings which is passed into a bunch of methods or constructors. (It's sort of used as a builder in that usually it's used when constructing an XmlWriter.) I can't think of any examples within the standard Java library right now, but they may exist somewhere...
If you do find yourself with lots of parameters though, it's worth taking another look at the design to check whether you shouldn't be grouping some of them together anyway, just as part of normal design.
Not exactly, because what Builder does is building an object.
So what would be the point of changing some method, which does who knows what, into a Builder?
What you should do with methods containing too many arguments is for example:
break it down to smaller methods,
use varargs
use some Collection to put into the same type arguments
Turning a method into a builder is possible but atypical. Apache HashCodeBuilder is one example, used like int hash = new HashCodeBuilder().append(a).append(b).build();, although in that specific case you might prefer to just use a method with varargs, like Guava's Objects.hashCode, used like int hash = Objects.hashCode(a, b);.
A method which takes a large number of arguments of different types is ill-suited to varargs, so you might find a builder appropriate, or you might want to consider reducing the amount of work that is being done in that method, or encapsulating the arguments in some other composite type.