On the Dark Side of Code Generation (or How Not to Use the Force.)
by Chad Finsterwald
Contents
Intro:
Before I start, let me say that I love code generation as much
(if not more) than the next person. I have tasted of the fruit of
QuickCode, I have
nursed at the bosom of CodeSmith,
I have slacked my thirst on
The Pragmatic Programmer , and
I have lain more than one night with any number of other code generators and wizards.
But for all the pleasure (and ease of mind) they have given me, there is a dark side which
I believe needs to be spoken of.
Recently I was called upon to finish a project that an other unnamed (and non-CoreWeb affiliated)
developer worked on. The
project was a relatively straight forward e-commerce site. The other developer
had divided it into two projects --a web project which held the web pages and a little bit of web related code, and
a class library which was comprised of his business logic and database layer. So far, so good...
Or so I was to believe.
On closer inspection it turned out that the developer had code generated themselves a
Potemkin Village --for those of you not familiar with the term, a
Potemkin Village
is a facade erected to decieve the eyes but contains little substance. Methods that looked
like they should do something --e.g, user.Update() or payment.Invoice()-- were just hollow
shells. Worse than that, methods were auto generated that were not appropriate given
the particulars of the application, like payment.Update() or invoice.Delete().
Clearly what had happened here is the work of developer half-crazed after a night of huffing
CodeSmith and drinking Tab. The silver lining of this event, if there is one, is that
it lead me to formulate my Three Evils of Code Generation.
Evil 1: Over Growth
I confess I've never seen the movie, but the phrase "Constant Gardner" seems apt. Namely,
when you generate code be sure to remove those methods that do not make sense given the
particulars of the situtation. For example, auto generating your CRUD operations for
your database abstraction layer is a HUGE time saver. (We use a homegrown CodeSmith template
for this purpose.) But if certain operations are not appropriate, like delete for an Invoice,
then remove them. Always pluck the weeds from you code garden because an API not only expresses
what you can do to a class, but also express your intent.
Evil 2: Empty Promises
After a few days of coding I thought that I cleared the weeds and things were starting to bloom.
When running the code, however, some troubling oddness remained and a foul oder rose up from
the application. It turns out that there were methods like this:
public bool SaveUser(User u)
{
return true ;
}
From my perspective, it was a pack of lies and empty promises.
When calling the code, it looked the user was being saved. But alas, no database entry
was created and no warning given. So to the second evil, if you have not coded your method
and just created a stub then SAY SO! Rather than returning a lie, throw an exception or at
least log or assert something. In other words, what should have been there is:
public bool SaveUser(User u)
{
throw new NotImplementedException("I regret this is not implemented,
please accept my apologies.");
}
Evil 3: An Idle Keyboard...
This last evil is perhaps the most general, which is the code generation
is no excuse for lazy coding. Code generation is a tool and like any other tool at your
disposal, it should be used responsibly. A sober use of code generation can save a lot
of time, but a drunken bacchanalia of orgiastic code generation is just that:
a drunken bacchanalia of orgiastic code generation.
Carefully choose what parts of your application should be auto generated, then review the
code that is created and prune the excess. Understand what your code generation is doing
and don't just accept the code that is created. Finally treat the code that is generated
as your own and apply the same exacting standards to it that you would apply to something
you wrote.
Above all please remember:
"Fear leads to anger, anger leads to hate, and hate leads to crappy auto generated code that show no concern for craftsmanship or other developers."