I'm reading 'Clean Code' from Robert C. Martin and I can't fully understand the 'Have No Side Effects' and 'Output Arguments' sections on pages 44 to 45.
In the 'Have No Side Effects' section it is stated that changes passed to parameters of a method are considered side effects and should not be done.
In the 'Output Arguments' section, it is stated that the parameters of a method should not be mutated. A method should only change the state of its owning object if some state has to be changed.
I do understand that side effects and output arguments can lead to confusing behavior and bugs if the method which does specify this behavior is called by a client who is not fully aware of that. Also, this is problematic when working in a multi-thread environment.
But with respect that the 'Clean Code' book is written based on examples with Java, I'm confused.
Let's take a look at an example. Let's assume we have a player class:
public class Player {
private int healthPoints;
private boolean alive = true;
public Player(int healthPoints) {
if(healthPoints < 1) {
throw new IllegalArgumentException();
}
this.healthPoints = healthPoints;
}
public boolean isAlive() {
return this.alive;
}
public void fight(Player otherPlayer) {
//do some fighting which will change this instance
// but also the otherPlayer instance
}
}
If we now call the following function:
player1.fight(player2);
This will change the status of player1 and also the status of player2. This is discouraged by Robert C. Martin in most cases. But in reality, I see this pattern a lot. The most Java programs really on mutation and objects are changed outside the scope in which they have been created.
If we create a battle which changes both players, it is even worse because now the other object mutates two parameters inside its method:
battle.fight(player1, player2)
Do I miss something here? When is it ok to mutate parameters inside a method(in Java)? I asked a quite similar question some time ago(Is mutating object-parameters in a method(in Java) a bad practice?).