views:

179

answers:

5

I have this method, that can return three different response.

At first, it was supposed just only return two, so I make its return type to Boolean

like:

public static boolean isLoteWaitingForImage()

And some business logic came out with that it can has another result, so the method was modified to

public static boolean isLoteWaitingForImage() throws ImageNotPendingException 

If a certain select return a null value, but one row its return true, if its not null i will return false. If no row was acquired from the select I will throw an ImageNotPendingException cause it doesn't apply for the given filters in the where clause.


Also thought about doing it in this Way, I have this new Class with the types that are valid to return from the method isLoteWaitingForImage(), with 3 constants properties called:

public class LoteResponse {
    public static int VALID = 1;
    public static int INVALID = 2;
    public static int NO_IMAGE_PENDING = 3;
}

So I will have this new method:

public static int isLoteWaitingForImage() {

    return LoteResponse.VALID;
}

Having this on table, I have these two questions:

  • Any "other" idea about how to accomplish this needing?

  • Which method is a better practice?

+10  A: 

Yes, that looks like an abuse to me.

It would be reasonable to throw the exception if the method simply shouldn't be called when no image is pending. Can the client always know that? Does it represent a bug, or something else going badly wrong for them to be calling it in that state? If not, don't use an exception.

It looks to me like you need an enum.

public enum LoteResponseState
{
    Valid,
    Invalid,
    NoImagePending;
}

public static LoteResponseState getLoteState()
{
    ...
}
Jon Skeet
@Jon Skeet: you've missed 'java' tag:)
Roman
@Roman: Gah, you're right. Still, it was a small change :)
Jon Skeet
This is exactly what I was looking for, thanks.
Garis Suero
Another Question, I have this class where I have those methods validation against DB. where should I locate those new `enum`, in the same `class`?
Garis Suero
@Garis: Could be a nested enum, or it could be completely separate. It's up to you.
Jon Skeet
A: 

Go for the exception way. It does have a more explicit interface to the caller. If the caller needs to process this ImageNotPendingException make it an Checked Exception.

Returning enum is a bizarre thing as it diminishes encapsulation by delegating business detail and processing to the caller. This way the caller needs to know way too much of the calee.

Sorry about my bad english.

Leonardo Figueiredo
Don't agree at all. Exceptions are incredibly expensive (generating that call stack is not a walk in the park) and should not be used for intentional control-flow.
Kirk Woll
Maybe, maybe not. javax.persistence.Query is hated because it throws Runtime exceptions for business cases.How about the encapsulation commment? Agree? Dont Agree?
Leonardo Figueiredo
Exceptions should rarely be used for control flow. Regarding enumerations, I fail to see your logic. If the return value doesn't have a strongly-defined meaning, how can it be used for anything? Even constants have an absolute meaning that the caller should be aware of; an enum just wraps it better.
Tim
+5  A: 
  • If you expect the code that calls isLoteWaitingForImage() to be directly responsible for handling the "no image pending" condition as well as the others, then use the multiple return values, but use an enum, not ints!
  • If the "no image pending" condition cannot be usefully handled by the immediate calling code and instead would usually be handled higher up the call stack, then the exception is the better option.
Michael Borgwardt
for the sake of learning, could you elaborate why one shouldn't return int? I would have thought it would be easiest to return -1,0,1 for three possibilities..
posdef
@posdef: Because it's easy to lose track of what the individual values mean, both when working on the code and trying to read it. Giving names to the conditions will save maintenance problems.
David Thornley
well I presume that makes sense if the project is large and there is no logical connection between the states and ints. In MATLAB one often uses a negative number to return a state that is wrong/faulty/erroneous..
posdef
@posdef - they are called magic numbers and are generally considered evil when there are multiple alternatives which are much better. Constants are a better alternative, while enums would be the preferred approach. Enums define specific constraints, is much better OO and is easily adaptable to future additions.
Robin
Thanks for your help Michael.
Garis Suero
@posdef: Enums have several big advantages: 1) Prevent using invalid values. 2) Prevent using the same value for two different things. 3) They're type safe (can't use the wrong constant) 4) The name is still available when the values get passed around or stored somewhere and you're logging it or looking at it in a debugger
Michael Borgwardt
posdef
+1  A: 

I definitely agree that an enum is the best choice.

As a general rule, if a certain operation is not considered a serious error that will rarely occur, you should not throw an exception. Throw exceptions only for errors that the current method cannot have any way of handling in a useful way, but not as a typical return value.

ChessWhiz
+1  A: 

I am no expert so don't take this as a best-practice advice, but I think using exceptions in this particular case seems like an overkill. I would go for some simple return values as mentioned above.

If you really want to keep track of the situation, for whatever debugging or developing reason, you could perhaps throw RuntimeException("why a runtime exception is thrown") instead. Writing an own Exception seems too excessive if you are not doing something particular with the exception.

I hope that makes some sense. :)

posdef