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

Asked

Viewed 701 times

7

I’m playing a card game in Java, and one of the classes is responsible for starting the game. In the builder, I get the number of players who will participate. I am doing the validation of the amount of players in the constructor itself, but how it should act if the user informs a number below or above the condition established by the program?

Should I make a specific exception and prevent the instantiation of the object? There are best practices for situations like this?

  • 2

    Validate this before going to the constructor, and tell the user q is invalid, allowing it to report again. Throwing exception is not a solution to anything, alias, is a bad practice. Exceptions is to be used in "exceptions", as the name says.

  • @Shall I then validate it as a method independent of the class I intend to instantiate? It would be interesting to have a class only for the?

  • I don’t know, it depends. If it’s too many validations, it would be a case.

3 answers

7

The class shall be responsible for avoiding being instantiated in a non-valid state.

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

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

  • A good practice therefore would be to check user data in a class intended only for this specific test?

  • 1

    Data entry validation has to be done to avoid the exception. Whether it is done in a separate class or not depends on the type, size or complexity of the application.

  • @ramaral generally I agree with this comment, but if it is something very silly, disposable, then anything goes :)

  • @Maniero You are referring to that it is not always necessary to validate the input?

  • Application size.

6

Yes, making an exception is recommended.

Ideally, a builder should never return a poorly constructed or incorrectly constructed object. If due to the fact that the parameters are not adequate, the constructor cannot construct the object, throw the exception.

In the case, IllegalArgumentException is a good candidate to be launched:

public class PartidaDoJogo {

    // ...

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

        // ...
    }

    // ...

}

In fact, not only constructors, 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, which makes systems easier to design and test. With this, programming errors will manifest immediately, enabling its correction and will have a smaller chance to mess with other parts of the system even when they occur.

  • Thank you for the answer! I had actually found in some sources the suggestion of using Illegalargumentexception for such cases. The staff here also suggested to check the data before moving to the class I want to instantiate, so I think the ideal is to do this prior check and in the Constructor make sure to use the Exception. The thinking is right?

  • 1

    @Lucasdirani Yes, that’s correct.

6


The analysis is never so simple, everything depends on context, but in general this is it, should throw an exception preventing the object to be built. Not being able to create an object is usually an exceptional case, the normal would be to create the object without problems. Note that the exception in general is a programming error. A test should make it be launched and you should fix.

In some cases it may be that create an invalid situation with null is interesting, but it is not so common and only casting the exception can do it in the builder (a Simple Factory can return the null). You can see that several objects when they cannot be created are null and do not generate an exception, so it is a solution that makes sense. Just don’t push this. This solution is better when the language helps avoid nulls, which is not the case with Java, which has not prevented the language from adopting the solution several times.

Make it clear that an invalid object should not be built. How to prevent this can vary a little. A null is an invalid object, but not an invalid object.

I’m not saying I can’t do that either.

Particularly I would use validation as a last resort when everything failed before, I would try not to let a wrong argument be passed. Popping validation during object creation is exceptional because the error was calling the constructor invalid.

I’ve seen some cases and I’ve thought about making more and more a static method utility that does a validation and only after going through it is that the creation of the object is performed, so you already know that everything will work. You can only not validate in the constructor because nothing requires that this utility be called before the constructor, and it would be even complicated to maintain 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 (or at least it was, it has changed she has preferred to use Factories and return a Optional). So just leave the exception is not wrong, just not good.

I would prefer it had a different mechanism to indicate programming error, which I think is the case, but as there is, the exception is interesting Now you have.

You just won’t put one try-catch to try to solve when creating this object. Not that there is no situation that cannot be useful, but it is rare. Usually you have to stop the wrong creation before.

Anything can when it makes sense. That’s why I always say that following recipes doesn’t work, you have to understand why you’re doing it.

Take a look at How and when to build a valid state object?.

  • 1

    Taking into account that it is of the same type, I would also check before creating an object.

  • @Maniero You would then advise to create a class responsible for validating the data before it is passed to the class I wish to instantiate?

  • 1

    @Lucasdirani I do not know if create a class, I edited to improve this.

  • @Maniero Perfeito, thanks even for the help, that’s what I was looking for. I also thank everyone who came to answer my question! :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.