What to do when the argument passed in the constructor is invalid?

6

I'm doing a card game in Java, and one of the classes takes responsibility for starting the game. In the constructor, I get the number of players that will participate. I am doing the validation of the amount of players in the constructor itself, but how should I act if the user reports a number below or above the condition set by the program?

Should I throw a specific exception and prevent object instantiation? Is there best practice for such situations?

    
asked by anonymous 27.09.2017 / 23:32

3 answers

5

The analysis is never so simple, it all depends on context, but in general, that is the same, you should throw an exception preventing the object from being built. Failing to create an object is often an exceptional case, the normal should be to create the object without problems. Note that the exception in general is a programming error. A test should get it thrown and you should fix it.

In some cases it may be that creating an invalid situation with null is interesting , but it is not as common. You can see that multiple objects when they can not be created become null and non-exceptable, so it's a solution that makes sense. Just do not abuse it. This solution is best when the language helps to avoid nulls, which is not the case with Java, which has not prevented the language from adopting this solution several times.

Make it clear that an object in an invalid state should not be built. How to prevent this can vary slightly. A null is an invalid object, but not an object created in an invalid state.

I also do not say that you can not do this ever, you can have that case pertinent.

Particularly I would use validation as a last resort when everything else failed before, I would try not to let a wrong argument be passed. Bursting validation during object creation is exceptional because the error was having called the constructor in an invalid form.

I've seen a few cases and I've been thinking of doing more and more a static utility method that does a validation and only after going through it is that object creation is performed, so you already know that everything will work. Just can not fail to validate in the constructor because nothing requires that this utility be called before the constructor, and it would even be complicated to keep state indicating that it was validated, it would just be a facility.

I know that the philosophy of the Java community is to abuse exceptions. So just leave the exception is not wrong, just do not think good.

I would rather have a different mechanism to indicate programming error, which I think is the case, but as it has not, the exception is interesting. Just do not put a try-catch to try to solve when creating this object. Not that there is no situation that can not be useful, but it is rare. Usually have to prevent the wrong creation before.

Everything can when it makes sense. That's why I always say that following recipes does not work, you have to understand why you're doing it.

    
27.09.2017 / 23:45
6

The class should be responsible for avoiding being instantiated in an invalid state.

Therefore, in the constructor, past values should be checked and an exception should be thrown if they are invalid.

However, since this value is provided by the user it must also be checked before attempting to instantiate the object. Note should not be used a try/catch block for this.

    
27.09.2017 / 23:45
5

Yes, throwing an exception is the recommended one.

Ideally, a constructor should never return an improperly constructed or incorrectly constructed object. If, because the parameters are not suitable, the constructor can not construct the object, throw the exception.

In this case, IllegalArgumentException is a good candidate to launch:

public class PartidaDoJogo {

    // ...

    public PartidaDoJogo(int numeroDeJogadores) {
        if (numeroDeJogadores < 4) {
            throw new IllegalArgumentException("O número mínimo de jogadores é 4.");
        }

        // ...
    }

    // ...

}

By the way, not just builders, but no method should accept invalid parameters. Whenever your method or constructor receives an invalid parameter or is otherwise misused, throw an exception. This makes your code more robust by having more safeguards that prevent your objects from entering invalid states, making systems easier to design and test. With this, programming errors will manifest immediately, enabling their correction and will have a smaller chance of messing with other parts of the system even when they occur.

    
27.09.2017 / 23:44