“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
Martin Fowler
This week in our clean coding practices, we discuss method parameters (arguments). Encountering too many parameters poses an issue that might look rather simple, but is mostly disturbing. This might be caused by the reasons below:
- Too many parameters amount to a method that is too complicated or has many functionalities, raising the concern that a slight change in its implementation could have an adverse impact on clients.
- Interfaces might be affected by the introduction of new parameters.
- The order of parameters might be confusing, although some IDEs can be helpful.
- Parameters to which the coder might assign a default value need to be located at the end, complicating things when the coder aspires to add a new parameter.
For instance, let’s imagine that the Java method below is a function which calculates the amount of tax an employee is required to pay according to certain parameters:
public BigDecimal(int age, boolean isMarried, int numberOfDependent, BigDecimal salary,
string taxCategory, boolean isExpat, BigDecimal extraIncomings) {
….
}
As you see, it looks like the method will soon go out of control. No one would really want to be the client of this method. Besides, we are not sure whether it abides by the Single Responsibility Principle, meaning that each method needs to have one single functionality.
Then, how many parameters is too many?
It is not possible to give an exact number. According to Uncle Bob, you need to use a maximum of three parameters. You need to aim for the minimum number of parameters as much as possible.
How to reduce the number of parameters?
With the help of a refractor, you can both reduce the number of your parameters and render your code easier to read and test. Firstly, you need to pay attention to read well, and grasp its implementation beforehand. Another thing to keep in mind is to have unit tests, an indispensable feature of all code changes and refractors.
Generally, two methods are used to reduce the number of parameters:
- Extract Method: If you make sure that the method has more than one functionality, you can refract it by dividing it into smaller units. That would also divide the parameters.
- Parameter Object: In case you cannot divide the method, you can unite parameters having the same content under objects. In the example above, we can unite the parameters under two objects: Person Object (class) which has personal data, and Payment Object which has financial data.
class Person {
long id;
int age;
boolean isMarried;
int numberOfDependent;
boolean isExpat;
}
class Payment {
long person_id;
BigDecimal salary;
string taxCategory;
BigDecimal extraIncomings;
}
Once our objects are finalized, we can use them as parameters. In this case, our sample method will look as follows:
public BigDecimal(Person person, Payment payment) {
….
}
You can take a step further and suffice it to submit the Person Object and embed Payment Object within the method. This completely depends on your design!