I like to code as little as possible.

I am not referring to how much time I spend coding, but more how terse and compact ("neat") the code is. If it's growing hairs trim them. If it's more than one complete thought, extract method.

One thing that's been causing me to grit my teeth a lot lately seems to be caused whenever I hear the term, "error handling," usually like, "look at that code! it's crap! There's no error handling!" where, in my opinion, error handling has no business being. It hurts even more when the person is someone I respect and otherwise agree with on all matters technical.

Extraneous error handling seems to me to be one the fastest ways for code to go from simple and clean:

to stressed out and hairy:

For a long time, when I first started learning .NET, I had this C++/COM baggage I brought with me, where I thought HRESULTs and IErrorInfo was the right way to do error handling. I had brief experience working with java and remember being shocked at how some java programmers thought the ratio of "catch" to other keywords in their programs should be approaching 1:1. I had concluded that "try" was bad, and .NET was worse off because of it.

Then I read what the P&P Team thought about the exceptions and breathed a sigh of relief. I had my strategy:

Exception Propagation

There are three main ways to propagate exceptions:

  • Let the exception propagate automatically

    With this approach, you do nothing and deliberately ignore the exception. This causes the control to move immediately from the current code block up the call stack until a catch block with a filter that matches the exception type is found.

...

(emphasis mine)

This is how I think 99% of code should handle exception, just as it's how I think 99% or bystanders should handle high speed car chases. Don't do anything! Let someone else who knows what they are doing handle it.

For this to work, you often need to alter other bad habits as well, such as instead of "try { DoSomethingToFileThatMightNotExist(fileName); } catch (FileNotFoundException) { /* ignore */ }" say "if (File.Exists(fileName)) DoSomethingToFileThatMightNotExist(fileName); }".

This also helps with debugging. Who likes it when you turn on "Stop when exception is thrown" in the debugger only to find there are a gazillion exceptions you don't care about being caught by code that ignores them?

All this leads me to see "try" as a code smell. I look extra hard at code with "try" and even harder at code with "catch". If I can, I refactor them away as quickly as I can.

Ideally, a user facing program should have only one place where errors are handled: the place where it decides how much to show to the user and how much to report to you via some other channel.

This helps me keep my code small, neat, and clean.


 
Categories: debugging | design | refactoring

Last night I was working on something and suddenly found myself needing about 30 really simple ActiveRecord classes. I figured it was about time to stop writing these manually each time.

Looking at the CastleProject.org site, and seeing that the status of ActiveRecordGenerator was frozen, I briefly considered writing my own little tool (or just modifying ActiveRecordGenerator as needed) to do the job. After another 10 minutes, I finally broke down and made a CodeSmith template (we've got CodeSmith, but for some subconscious reason I keep avoiding using it.)

This was fairly straightforward, and after 20 minutes or so, I had the template I wanted, and started generating classes. After another 20 minutes I had added some things I missed the first time and everything was great.

After completing this, I looked at what I had done, and found myself thinking: this is alot of cruft.

Let me mention that all 30 classes had basically the same set of properties. I briefly considered writing a generic class, but didn't think there would be a way to get the name of the class into the '[ActiveRecord("MyTableNameIs")]' attribute. That, and a small handful of special rules, were the only things different about these classes.

I was thinking: A lisp-like macro would have been really useful. Why don't we have lisp macros in OO languages like C#? I've always fealt (but not agreed) that it's because OO leads you to composition instead of code generation. I could have written one base class with the properties I wanted, then 30 derived classes with the right names and attributes. That is still too much typing, though, and I would have used code generation anyway. I chose not to relate these classes, as they are not really related in this domain anyway, only functionally and structurally related.

I am not sure what the best answer to this type of design problem is, but I know I haven't found it. Code Generation is a jack-hammer in the face of the problem of code duplication caused by imperfect design. It gets me through the barriers, but the barriers were trying to tell me something.

Frameworks and tools (like ActiveRecordGenerator, or even better - Streamlined) that generate applications based on meta data are becoming very popular. Are these tools just reactions to the lack of good DSL tools or lisp-macro-like facilities - i.e., why am I writing my C# application in Code Smith templates and not in C#?


 
Categories: design | architecture | refactoring | agile