2 added 794 characters in body
source | link

Example 1

Example 2

Example 3

FinallyFrom those examples, the only cases where replacing a magical value by a constant wouldyou may have an impression that numbers should be uselessreplaced by constants in every case. This is where not onlytrue. In some situations, having a constant doesn't lead to code improvement.

Take the value is clearfollowing piece of code:

class Point
{
    ...
    public void Reset()
    {
        x, y = (0, 0);
    }
}

If you try to replace zeroes by itselfa variable, but where it's practically impossiblethe difficulty would be to find a meaningful name for the constant. How would you name it? (except givingZeroPosition? Base? Default? Introducing a constant here would not enhance the code in any way. It would make it slightly longer, and just that.

Such cases are however rare. So any time you find a number in code, make the effort trying to find how the code can be refactored. Ask yourself if there is a business meaning to the number. If yes, a constant is mandatory. If no, how would you name of the number itself)? If you find a meaningful name, that's great. Such casesIf not, chances are pretty rareyou found a case where the constant is unnecessary.

Finally, the only cases where replacing a magical value by a constant would be useless is where not only the value is clear by itself, but where it's practically impossible to find a meaningful name for the constant (except giving it the name of the number itself). Such cases are pretty rare.

Example 1

Example 2

Example 3

From those examples, you may have an impression that numbers should be replaced by constants in every case. This is not true. In some situations, having a constant doesn't lead to code improvement.

Take the following piece of code:

class Point
{
    ...
    public void Reset()
    {
        x, y = (0, 0);
    }
}

If you try to replace zeroes by a variable, the difficulty would be to find a meaningful name. How would you name it? ZeroPosition? Base? Default? Introducing a constant here would not enhance the code in any way. It would make it slightly longer, and just that.

Such cases are however rare. So any time you find a number in code, make the effort trying to find how the code can be refactored. Ask yourself if there is a business meaning to the number. If yes, a constant is mandatory. If no, how would you name the number? If you find a meaningful name, that's great. If not, chances are you found a case where the constant is unnecessary.

1
source | link

There are several issues with this piece of code, which, by the way, can be shortened like this:

public List<Money> getMoneyByPersons() {
    return persons.size() == 1 ?
        moneyService.getMoneyIfHasOnePerson() :
        moneyService.getMoney(); 
}
  1. It is unclear why one person is a special case. I suppose that there is a specific business rule which tells that getting money from one person is radically different from getting money from several persons. However, I have to go and look inside both getMoneyIfHasOnePerson and getMoney, hoping to understand why are there distinct cases.

  2. The name getMoneyIfHasOnePerson doesn't look right. From the name, I would expect the method to check if there is a single person and, if this is the case, get money from him; otherwise, do nothing. From your code, this is not what is happening (or you're doing the condition twice).

  3. Is there any reason to return a List<Money> rather than a collection?

Back to your question, because it is unclear why there is a special treatment for one person, the digit one should be replaced by a constant, unless there is another way to make the rules explicit. Here, one is not very different from any other magic number. You could have business rules telling that the special treatment applies to one, two or three persons, or only to more than twelve persons.

How can I distinguish context to choose the best solution?

You do whatever makes your code more explicit.

Imagine the following piece of code:

if (sequence.size() == 0) {
    return null;
}

return this.processSequence(sequence);

Is zero here a magical value? The code is rather clear: if there are no elements in the sequence, let's not process it and return a special value. But this code can also be rewritten like this:

if (sequence.isEmpty()) {
    return null;
}

return this.processSequence(sequence);

Here, no more constant, and the code is even clearer.

Take another piece of code:

const result = Math.round(input * 1000) / 1000;

It doesn't take too much time to understand what it does in languages such as JavaScript which don't have round(value, precision) overload.

Now, if you want to introduce a constant, how would it be called? The closest term you can get is Precision. So:

const precision = 1000;
const result = Math.round(input * precision) / precision;

Does it improve readability? It might be. Here, the value of a constant is rather limited, and you may ask yourself if you really need to perform the refactoring. The nice thing here is that now, the precision is declared only once, so if it changes, you don't risk making a mistake such as:

const result = Math.round(input * 100) / 1000;

changing the value in one location, and forgetting to do it in the other one.

Finally, the only cases where replacing a magical value by a constant would be useless is where not only the value is clear by itself, but where it's practically impossible to find a meaningful name for the constant (except giving it the name of the number itself). Such cases are pretty rare.