Tuesday, August 26, 2008
Greatest pair-programming tool ever?
This has to be one of the greatest thing for pair-programmers since large wide-screen monitors. I haven't tried it yet though, so perhaps I'm wrong. :) Seems like a really really nice plug-in for Eclipse, though.
Monday, August 25, 2008
Checked exceptions exposes implementation?
I've read and heard the phrase Checked exceptions are evil! They expose implementation details! a couple of time (last time was an entartaining read for several other reasons...). I really don't understand this statement (hey, you, explain to me please).
How can the
For me, checked exceptions are vital to enforce proper error handling. But this can (probably) only be achieved if the exceptions fits the problem domain. For instance, throwing an
One of the most important lesson I've learnt from using exceptions is the importance of doing try-catch-wrap-throw. For example, if an implementation of
A couple of times I've let domain exceptions inherit from each other to define that, for example, a
But as I said, this is not very common for me. Although if you are developing a library and wish the user to have the ability to handle the different error-cases separetely, then could be useful.
Well, these are some of my thoughts on checked exceptions. In summary: I think they're good stuff if done well. :)
How can the
EncodingException
part of the code below expose implementation details when void encode()
does not? The first say I can fail to encode, the latter say I can encode. What's the difference?
interface Encoder {
void encode(Object o) throws EncodingException;
}
For me, checked exceptions are vital to enforce proper error handling. But this can (probably) only be achieved if the exceptions fits the problem domain. For instance, throwing an
IOException
in the interface above would be really really bad because it exposes details of the Encoder
, e.g., that is uses the network, or whatever. On the other hand, the only thing EncodingException
exposes is that an Encoder
can fail to encode the provided object. That's not an implementation detail, I think, that's the Encoder
being honest and not hiding it flaws.One of the most important lesson I've learnt from using exceptions is the importance of doing try-catch-wrap-throw. For example, if an implementation of
Encoder
uses a method that throws IOException
then the proper way of handling such exception is to catch it, wrap it in a EncodingException
and throw it to the client of the Encoder
. This cleans up ugly interfaces that throws many exceptions, resulting in clear description (with semantics, yeay!) of what can go wrong when a method is called. Exceptions that fits the problem domain is the key.A couple of times I've let domain exceptions inherit from each other to define that, for example, a
RangeException
is a ConfigurationException
. This seemed like a good idea to me at the time, however, it seldom helped the design (it didn't make it worse either, though). In fact, the only time I find it useful is when you need to distinguish between thrown exceptions in one place but handle them in the same way in a nother place. For example (where LeftException
and RightException
inherits from BaseException
):
interface Something {
void doIt() throws LeftException, RightException;
}
class HandlesExceptionsSeparately {
void method(Something s) {
try {
s.doIt()
} catch(LeftException e) {
// handle it
} catch (RightException e) {
// handle in another way) {
}
}
}
class HandlesExceptionsTogether {
void method(Something s) {
try {
s.doIt()
} catch(BaseException e) {
// handles both
}
}
}
But as I said, this is not very common for me. Although if you are developing a library and wish the user to have the ability to handle the different error-cases separetely, then could be useful.
Well, these are some of my thoughts on checked exceptions. In summary: I think they're good stuff if done well. :)
Etiketter:
exception,
inheritance,
java,
opinions,
programming
Sunday, August 3, 2008
Fear and Loathing in Parse Vegas
Martin Fowler writes about parser fear and I have to say "guilty as charged". I've done a few DSL but all have be so simple that I could hand-write a parser using regular expressions and other string manipulations. To be honest, the resulting parser would probably be easier to understand, maintain, etc, if it was developed using a proper grammar and a parser generator. Despite (knowing) this, I kept writing those convoluted hand-written parsers.
I did the compiler class at the university and I'm intressted in most things programming langage related, e.g., compilers and parsers. Despite this I never actually done a parser (with proper grammar) by my self. Why? I had parser fear.
Fowler writes:
I think the last bullet explains why I never did a proper-grammar-parser by my self.
However, the last time I had to write a parser I (finally) realized that a proper-grammar-parser was a better idea than trying to hand-write something convoluted. The parser should be implemented in Ruby, so I googled (is that a verb now?) and found a generic recursive decent parser -- all I had to do was to write the grammar, which was straight forward.
I did the compiler class at the university and I'm intressted in most things programming langage related, e.g., compilers and parsers. Despite this I never actually done a parser (with proper grammar) by my self. Why? I had parser fear.
Fowler writes:
So why is there an unreasonable fear of writing parsers for DSLs? I think it boils down to two main reasons.
- You didn't do the compiler class at university and therefore think parsers are scary.
- You did do the compiler class at university and are therefore convinced that parsers are scary.
I think the last bullet explains why I never did a proper-grammar-parser by my self.
However, the last time I had to write a parser I (finally) realized that a proper-grammar-parser was a better idea than trying to hand-write something convoluted. The parser should be implemented in Ruby, so I googled (is that a verb now?) and found a generic recursive decent parser -- all I had to do was to write the grammar, which was straight forward.
There were several resons that finally made me take the step to use a proper parser:
- The language was complex enough to make my old approach unsuitable
- The parser was really easy to integrate with my other Ruby code
- No separate step for generating the parser (i.e. short turn-around time, and less complexity because there is no code generation)
Subscribe to:
Posts (Atom)