- Error Handling vs Method Overloading
- Multiple Nested If Statements
Error handling in programming languages allows software developers to build safeguards into their code to protect against possible exceptions or errors during runtime. Method overloading, on the other hand, allows developers to build multiple methods of the same name, but that act differently depending on their method signatures (ie: different parameters).
Lets take the following snipped of FuglyCode for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public boolean Tester( Object myObject ) { String myString; Integer myInt; try { // Save the string myString = ( String ) myObject; // Do more String stuff... } catch ( Exception e ) { // The object was not a string // Save the integer myInt = ( Integer ) myObject; // Do more Integer stuff... } return( true ); } |
Special thanks to jpuly for submitting this code. Submit your fugly code here.
Before we begin analyzing the fuglyness of this code, lets go over it to make sure we all understand what seems to be going on:
- At line 1, we enter our Tester method and receive an object
- At line 7, we attempt to save our object to a String variable
- At line 11, we catch any exception of type Exception (pretty much, we catch any exception)
- At line 15, we assume that the exception was caused by saving the object to a string, so we save our object to an Integer variable
One of the biggest problems with this code is that, although we accept any Exception type, we assume that the only reason our code would throw an exception would be because of the String cast on line 7. What if the myObject parameter is a String, and code does something on line 9 that throws an exception?
Obviously the exception will be caught and the catch block will be run. Because myObject is a string, however, the Integer cast on line 15 will throw an exception, and since we don’t have any code to handle and exception thrown at that line, our program will crash and burn.
So what could you do? Well, you could begin by using a much more specific Exception type. In fact, changing line 11 to “catch ( ClassCastException e )” would ensure that we only enter the catch block if the String cast on line 7 failed, although it wouldn’t protect against other exceptions being thrown, or against myObject being something other than a String or an Integer.
In this particular situation, we need to take a step back and look at the method as a whole. What are we trying to accomplish here? Does the code have to be so complicated? (Remember KISS!)
Truth is, our Tester method is using error handling to make a decision (if myObject is a String, do something, otherwise, do something else). Not only is this poor software design, but it fails to capitalize on the programming language’s built in ability to overload methods.
So, lets scrap the error handling altogether, and split this method into two similar methods with differing signatures:
1 2 3 4 5 6 7 8 9 10 | public boolean Tester( String myString ) { // Do String stuff... (optionally wrap in try/catch block) return( true ); } public boolean Tester( Integer myInt ) { // Do Integer stuff... (optionally wrap in try/catch block) return( true ); } |
And there we go! Now we have two methods with the same names (meaning our calling code doesn’t have to change). We also specify our parameter types, meaning that the compiler will not allow us to call Tester with anything other than either an Integer or a String. And as a final and optional touch, we can add error handling at lines 2 and 7, in case these lines risk throwing an exception.
If you have any questions, feel free to post them in the comments section below.
If you would like to ask your question privately, you can send it using the Contact Us form.
Do you have any FuglyCode you would like to share? If so, then submit it!

Comments
Leave a comment Trackback