tags:

views:

98

answers:

4
+3  Q: 

Method return type

Hi,

In my company, a system is designed to have 3 layers. Layer1 is responsible for business logic handling. Layer3 is calling back end systems. Layer2 sits between the two layers so that layer1 doesn't need to know about the back end systems. To relay information from layer3, layer2 needs to define interface to layer1.

For example, layer1 wants to check if a PIN from user is correct. It calls layer2 checkPin() method and then layer2 calls the relevant back end system. The checkPin() results could be: correctPin, inCorrectPin and internalError. At the moment, we defined the return type 'int'. So if layer2 returns 0, it means correctPin; if 1 is returned, it means inCorrectPin; if 9 is returned it means internalError.

It works. However I feel a bit uneasy about this approach. Are there better ways to do it? For example define an enum CheckPinResult{CORRECT_PIN,INCORRECT_PIN,INTERNAL_ERROR}, and return CheckPinResult type?

Thanks, Sarah

+1  A: 

Is it a reasonable common case that you get the internal error? If not, I would have checkPin return a boolean and throw an exception if there is an internal error (but then I'd probably call the method pinIsValid or something like that instead).

If it (for some reason) is an expected result to encounter the internal error, then a tri-state enum could probably work out well (I have a similar case in my current project).

Fredrik Mörk
+1  A: 

I like the enum approach. It's self-documenting and easily extensible. You can set the value returned by each one to match the 0, 1, 9 convention you have in place.

Throwing an exception is certainly a defensible approach, but throwing exceptions can be an expensive thing. I've always believed that they should be used to indicate truly exceptional situations. Having a bad pin may or may not be that exceptional depending on your business problem. If your process allows "five nines" reliability for pins, then I'd say that an exception would be a good way to go.

But if failure rates are more on the order of 1%, I'd say that a return value might be better. You might want to loop through a large lot of values and simply accumulate the part #s with failed pins as a large batch. It depends on how you use the error code.

duffymo
Our architect will definitely agree with you. He doesn't like the java exception mechanism at all.
sarahTheButterFly
Sadly I couldn't convince my colleagues to use enum. They said it's too much re-factoring work. :(
sarahTheButterFly
We're talking about changing the signature of a single method, right? If that's the case, it'd be easy for a tool like IntelliJ. How many times do you call this method? I wouldn't accept "too much" without some quantifiable evidence to support it.
duffymo
There are about 15 methods like checkPin(), which returns interger. That's why they said it's too much re-factoring work. From what I can see, it would be really beneficial for maintenance if enum is used.
sarahTheButterFly
A good refactoring IDE could do it. The argument isn't that strong, IMO.
duffymo
+1  A: 

Enum is certainly an improvement over integer return types and a perfectly valid approach. Another option would be to have a layer 2 signature such as:

public boolean isPINValid() throws InternalErrorException();

Since, I presume, internal errors are the exception, why not treat them as such?

Chris Knight
+1  A: 

This is a question of style. The way you described is a sort of C style to accomplish the goal. The java style is the following: checkPin(pin) should return a boolean. True meaning the pin is ok and false meaning it is not ok. If an error happens you throw an exception. Exceptions are the standard way of dealing with errors in Java. Exceptions are useful because they can have types and error messages to aid in debugging.

I say that the mechanism you are describing is a C style because in C the standard way to handle errors is to return an integer that maps to a define and then pass in by reference the value you are looking for (in this case a boolean). So in c you would have

int checkPin(int pin, bool &ans); //returns an error value.

Either way, I strongly recommend not returning the error value in the same place that you return the boolean. This creates confusion because a single value (the return value) should really only represent one thing. The error status and the answer to the question are two different things and so should be returned through different channels.

I hope that helped.

Luke Magill
Haha..you got it. C style. My colleague who defined the interface is from C background. It is so hard to persuade people from C background to use say enum.
sarahTheButterFly