Site Sponsors:
Enumeration -v- Exception? 
From 'enums to templates, both Sun/Oracle and Microsoft continue to learn allot from C/C++. Just as certainly however, many an old C/C++ 'hand will find allot of cohesive design patterns in Java, too.

Some ideas - like separating our 'readers from our 'writers - are good. Other ideas - like omitting pointers - are bad. Finally, some ideas - like favorings exceptions over enumerators - are just plain old ugly.

Exceptions Are Evil?


Not only are exceptions ugly, but the stack & memory cost of using exceptions can often make using exceptions unnecessarily expensive, too.

Is there a better way?

Well, for a start, let's consider how far too many of us often create a customized exception:


public class Exceptional
extends Exception {
// Often nothing else goes here.
// -We only want to create a
// new name?
}


The net effect of using an exception to simply create an enumerable response - as innocent as we might imagine it to be - is to create a code and memory sand-bar; A full blown class; An object to toss-around a slowly-unwinding stack .... only to be caught elsewhere ... by what effectively amounts to an extremely inefficient switch statement:


try {
...
}
catch(Exceptional ex) {
}
catch(IOException ex) {
}
catch(Exception ex) {
}


Indeed, if all we are looking for is a way to name something like Exceptional as an intra-process communication 'flag', then why not just forget about creating any type of Throwable? Why not simply use an enumeration, instead?

Benefits of Enumerations


Ever concerned with higher performance and efficiencies, in C/C++, we have traditionally been able to turn-off things like run-time type-identification and exceptions. Those reasons alone are part of why C++ will ever be far, far more efficient than .NET or Java.

But since enumerators arrived far, far latter in Java than they did in C/C++, developers continue on with what has become a traditional use of exceptions... Even when returning a simple C/C++-style enumeration would be far, far more understandable, & efficient:


public class Alternative {
enum Exceptional {
ea_Good,
ea_Bad,
ea_Ugly
}
public Exceptional Groovy() {
return Exceptional.ea_Good;
}
}


So rather than tossing a 50-pound 'thrown' wrecking-ball around our framework, why not simply return an open-ended enumeration (i.e. we can always add more enumerated names), instead?


public void Cool() {
switch(Groovy()) {
case ea_Good:
break;
case ea_Bad:
break;
case ea_Ugly:
break;
default:
break;
}
}


Indeed, rather than working so hard to merely let a future exception slip through our hands ... and unlike that legacy try/catch block ... when using a switch, that default: tag works a lot harder than any type of finally statement. Why? Because no super-block flags need to be set:


boolean imadoofus = false;
try {
...
}
catch(Exceptional ex) {
imadoofus = true;
}
catch(IOException ex) {
imadoofus = true;
}
catch(Exception ex) {
imadoofus = true;
}
finally {
if(imadoofus) {
...
}
}


Hence we are all learning.

Such noted however, perhaps we all need to keep-up with the ripple-effects whenever a standard is updated. Indeed, actually applying what-we-borrow from other camps often has some very favorable effects upon our legacy code-creation practices. In the case of preferring a single enumeration over a plethora of gratuitous exception class-creations, reserving the creation of custom Exceptions for managing far less-recoverable Error-type of 'throwables, may just be one more nice practice to get used to.

Return Result Paradigm Shift


Lastly, while most of us are in the habit of returning types from member functions (i.e. Java has no pointer-to-a-pointer ability), when returning enumerators instead of result-types we can opt to use mutable objects as parameters.


public Exceptional Groovy(final MyResult in, MyResult out) {
out.wrapMe = "Some Response";
return Exceptional.ea_Good;
}


Indeed, going a step farther - when we choose to manage read-only - yet mutable parameters - with a simple final keyword, then when using mutable-parameter-results we can also choose to (1) pass-in a mutable object-result as a parameter, (2) be sure that the parameter-result-type has both an assignment and isNull() ability, and (3) now our code will be smaller, more efficient - as well as safer, too!


public void Cool() {
MyResult in = new MyResult();
MyResult out = new MyResult();
switch (Groovy(in, out)) {
case ea_Good:
break;
case ea_Bad:
break;
case ea_Ugly:
break;
default:
break;
}
}


Conclusion


After reading this article, I hope that you will consider using enumerators. IMO, the liberal use of even a single enumerator-set often combines together so as to make several versions of our products a lot more readable, maintainable, as well as easier to control.

Enjoy,

-Rn

(p.s. If you think that the idea of using enumeration in the place of tossing around exceptions is noteworthy, than you might also enjoy another post on using enumerators, too.)


[ add comment ] ( 847 views )   |  permalink  |  related link

<<First <Back | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Next> Last>>