to be there. He knew that he was in over his head, and he needed help badly.
He could see that clearly now. When the project started, the programming
team had just enough time to learn the syntax of the new language. They had
been using an object-oriented language for four years without ever producing
an object-oriented design. Their methodology called for one large develop-
ment cycle, which provided very little time to find all of the mistakes—and
even less time to recover. The insane argument at the time was that there was
no time for more than one iteration.
As a member of the audit team dispatched to help the customer pick up the
pieces, I was there to interview the programmer. My team had composed a
checklist of likely culprits: poor performance, obscure designs, and process
problems. We had written the same report many times, saving our customers
hundreds of thousands of dollars, but the interviews always provided addi-
tional weight and credibility to back up our assertions.
“Is your user interface pure HTML , then?” I asked.
“Yeah,” the programmer replied. “We tried applets, but that train crashed
and burned. We couldn't deal with the multiple firewalls, and our IT depart-
ment didn't think they would be able to keep up with the different browser
and JVM configurations.”
“So, where is the code that prints the returning HTML ?”
He winced and said, “Do you really want to go near that thing?” In truth, I
didn't want any part of it. I had done this long enough to know that this baby
would be too ugly for a mother to love, but this painful process would yield
one of the keys to the kingdom. As we reviewed the code, we confirmed that
this was an instance of what I now call the Magic Servlet antipattern, featured
in chapter 3 . The printout consisted of 30 pages of code, and 26 were all in a
single service method. The problem wasn't so much a bad design as a lack of
any design at all. We took a few notes and read a few more pages. While my
partner searched for the code fragment that processed the return trip, I looked
for the database code. After all, I had written a database performance book, and
many of the semiretired database problems were surfacing anew in Java code.
“Is this the only place that you connect to the database?” I asked.
“No,” he answered. “We actually connect six different times: to validate
the form, to get the claim, to get the customer, to handle error recovery, to
submit the claim, and to submit the customer.” I suppressed a triumphant
smile and again reviewed the code. Connection pooling is often neglected but
incredibly powerful. In chapter 7, the Connection Thrashing antipattern
shows how a method can spend up to half of its time managing connections,
repeating work that can usually be done once.