We have quite a lot of places in the source code of our application , where one class has many methods with same names and different parameters. Those methods always have all the parameters of a 'previous' method plus one more.
It's a result of long evolution (legacy code) and this thinking (I believe):
"There is a method M that does thing A. I need to do A + B. OK, I know … I will add a new parameter to M, create a new method for that, move code from M to the new method with one more parameter, do the A + B over there and call the new method from M with a default value of the new parameter."
Here is an example (in Java-like-language):
class DocumentHome {
(...)
public Document createDocument(String name) {
// just calls another method with default value of its parameter
return createDocument(name, -1);
}
public Document createDocument(String name, int minPagesCount) {
// just calls another method with default value of its parameter
return createDocument(name, minPagesCount, false);
}
public Document createDocument(String name, int minPagesCount, boolean firstPageBlank) {
// just calls another method with default value of its parameter
return createDocument(name, minPagesCount, false, "");
}
public Document createDocument(String name, int minPagesCount, boolean firstPageBlank, String title) {
// here the real work gets done
(...)
}
(...)
}
I feel like this is wrong. Not only that we can't keep adding new parameters like this forever, but the code hard to extend/change because of all the dependencies between methods.
Here are few ways how to do this better:
-
Introduce a parameter object:
class DocumentCreationParams { String name; int minPagesCount; boolean firstPageBlank; String title; (...) } class DokumentHome { public Document createDocument(DocumentCreationParams p) { // here the real work gets done (...) } }
-
Set the parameters to the
DocumentHome
object before we callcreateDocument()
@In DocumentHome dh = null; (...) dh.setName(...); dh.setMinPagesCount(...); dh.setFirstPageBlank(...); Document newDocument = dh.createDocument();
-
Separate the work into different methods and call them as needed:
@In DocumentHome dh = null; Document newDocument = dh.createDocument(); dh.changeName(newDocument, "name"); dh.addFirstBlankPage(newDocument); dh.changeMinPagesCount(new Document, 10);
My questions:
- Is the described problem really a problem?
- What do you think about suggested solutions? Which one would you prefer (based on your experience)?
- Can you think of any other solution?
Best Answer
Maybe try the builder pattern? (note: fairly random Google result :)
I cannot give a full rundown of why I prefer builder over the options you give, but you have identified a large problem with a lot of code. If you think you need more than two parameters to a method you probably have your code structured wrongly (and some would argue one!).
The problem with a params object is (unless the object you create is in some way real) you just push the problem up a level, and you end up with a cluster of unrelated parameters forming the 'object'.
Your other attempts look to me like someone reaching for the builder pattern but not quite getting there :)