iTextSharp frustrations

I’ve been working a lot with iTextSharp lately. It’s incredibly useful but also sparsely documented, and the design concept is far from obvious. Here’s what I mean.

You don’t instantiate a PdfDocument. even though its constructor is public. You instantiate a Document. It creates a PdfDocument behind your back.

“New Page” behavior is extra bewildering!

If you haven’t put anything onto a page, but call PdfWriter.NewPage(), you will not get a new page.

You can override this behavior by setting PdfWriter.PageEmpty to false. (You can’t set it to true!)

Guess what? Pulling the drawing context so you can position text by the pixel, and then doing so, doesn’t count as putting anything on the page.


"Hardening" sprints considered harmful

Why do you have hardening sprints? EVERY SPRINT is supposed to be hardening.

Some Scrum teams–whether formally or informally–have a recurring “hardening” sprint after every few regular sprints, in which they fix outstanding defects and make the system actually ready for delivery. This is a bad idea. Here’s why.

If you care about why you are “doing Agile,” you should care about the principles of Agile development, which include “early and continuous delivery
of valuable software.” Delivery. If you’re not continuously delivering software, you’re not Agile.

If you have legacy defects, which are any defects not tied to a current story, then those defects need to be made stories in their own right. If your current stories are implemented with defects, they are not done and you have no business considering them completed. If you haven’t integrated a pipeline from development to deployment, that is infrastructure! It’s not part of a sprint!

Make every sprint a “hardening sprint.” That way you always have a product to deliver. That way you are never wrong.

Legacy Code: Wrap a method

I’m a big fan of Michael Feathers’s book Working Effectively With Legacy Code, and now and then I reread it because there’s always something to refresh or remind me.

Right now I’m looking at the “Wrap Method (67)” technique. It’s really simple. I’m just restating it here.
Continue reading “Legacy Code: Wrap a method”

.NET people make everything so difficult

I do lots and lots of development with the .NET platform, mainly because the corporations in the Cleveland area that have money to fund large projects are Microsoft shops.

I used to have a real problem with Microsoft development, back when it was all Windows 95; the tools were expensive, flaky, and unreliable. Since then, the tools have improved to an amazing degree; now I can write code that actually works consistently on more than one computer, and it’s not utterly ridiculous to run Windows on servers anymore. So there’s that.

But in just the last couple of days, I’ve gotten back into the Ruby on Rails environment. Partly, I’m jamming with my college homie Dave Stagner on his amazing Congruence product; and also, I had to update this old Perl script that I’ve been using for years to sort my incoming email.

Continue reading “.NET people make everything so difficult”

Don't have coding standards

I’m doing a new thing now!

If you’re currently on my eZine and announcements opt-in list–and you should be, because it’s usually not boring–you found out about it this morning.

Long story short, and not to kill the suspense, the main thing is that if you send me some problematic C# code, along with a very reasonable amount of money, I will turn around a solid code review, complete with prose narrative, suggestions, and maybe even bug fixes. (I’ll put all the details up next week, but that’s next week’s problem. You should be on the opt-in list!)

One thing I won’t do, though, is impose “coding standards.” I don’t think you should have them.

Why you shouldn’t have “coding standards”

Okay, that’s actually wrong. I do think you should have coding standards, even if you work by yourself as a lot of my fans do. Have a regular, standardized way of naming things. Of indenting. Of when to break something into more than one class. Of when to unroll loops.

Sure. There’s nothing wrong with that if it makes you feel better.

The benefit of having standards is that you don’t have to think about them. That’s why I’m saying… don’t have them.

Here’s what I really mean.

Again I’m going to play the “I’ve worked in sixty development shops” card. I’ve seen a lot of single developers, startups, growing concerns, flailing concerns, and mega-corporations do software development to a WIDE range of success. And pretty much always, someone senior at some point calls a meeting and says…

…Let’s Have Standards.

In practice, that means you spend a few hours in more meetings going over the oh-so-important issue of whether to name your classes in camelCase or PascalCase. Where the curly brackets go. You know, all that stuff that ReSharper already does for you.

I’m saying those meetings are not a productive use of time. Your deliverable becomes a set of rules that everyone either has to try hard to remember, or rules that nobody bothers to follow at all. And I keep asking, what is the problem you are trying to solve here? Nobody’s totally clear on that.

  • If your architecture is too complicated, reduce the architecture.
  • If you lack unit tests, build code with unit tests.
  • If your code is too tightly coupled, think about where the seams should go.
  • If it’s hard to find the class you want, pick better class names.
  • If you have a lot of duplicated code, refactor it to remove the duplication.
  • If your problem is excessive defects, then “standards” aren’t going to help at all.

So either you think about these rules and they get in your way, or you don’t follow them and they don’t help you. In any event, they don’t solve any actual known problem. Come on, when was the last time you honestly couldn’t get something to work because the curly braces were in the wrong place? Ever?

Here. Let’s make it easy.

Why not save everyone some time and annoyance and just use ReSharper? You can leave the default ruleset, which is a pretty reasonable one, or customize it if you really really want to, but the important thing is to set it up and not worry about ever again.

The main thing is to know what the problem is that you are trying to solve instead of getting excited about a solution that may not help you at all.

I’ve found that the shops that take more than about fifteen minutes, ever, to discuss “coding standards” are the ones with pretty severe process issues that “standards” won’t at all fix. The right path is directly to the source of those problems, not one of avoidance.


Adventures in version control

Branching in source control isn’t just for big shops. It also allows small shops to do big things without holding up the small things.

So I spent a lot of the weekend refactoring my Healthy Homes database system. (I know, what a party animal.) And after getting some solid work checked in, I realized it was definitely time to do a major refactoring of the Data Access Layer (DAL) code.

Continue reading “Adventures in version control”

Cost of convergence

You can’t afford to: create the installer, finish the release notes, and tie up all those little loose ends. Not for every increment. It takes a long time and the effort simply isn’t worth it.

I was recently developing a significant new feature on an ASP.NET application. The client’s regular dev team is located in India, but for this new feature they wanted somebody whom they could work with face-to-face, and having me dedicated to the project (for a short time) seemed like an advantage.

We started off really well. I was able to get into TFS for version control, connect to the development database, and add a few basic pages to get started.

Continue reading “Cost of convergence”

Stored Procedures aren't all that

I’m not sold on the very common corporate practice of requiring all database access to go through stored procedures. It’s not particularly efficient, it creates a lot of extra work for tiny benefits, and it cultivates code that’s duplicated and hard to find.

Now and then I check into The Daily WTF, partly because it’s funny and partly because it makes me feel a little better about some of the crazy code I’ve observed or been asked to maintain.

One in particular from about seven years ago amused me greatly, but not just in the train-wreck sense for a change. It addressed the very serious subject of putting all your database code into stored procedures. The comments are actually pretty illuminating.

Alex Papadimolous, actually being serious, wrote:

Though they take a bit more time to develop upfront, using database stored procedures are definitely the way to go for most information systems. They provide a looser coupling to the “data layer” by limiting the points of entry and offer stronger cohesion by breaking operations into reusable functionality.

I don’t think so, if by “most information systems” you mean the typical multi-tier business and financial databases that most of us maintain in our day jobs. I find that the looser coupling is almost always theoretical; it breaks down when you have to look at code from a year or two ago and figure out what the underlying stored procedure is actually doing instead of what you expect.

Continue reading “Stored Procedures aren't all that”

Does anybody still do WinForms? Validation.

So I was hung up last week on a data validation issue in WinForms. It’s a pretty simple desktop application to which I was adding a new Form for maintaining a parent-child-grandchild set of tables. DataGridView is my friend!

One column in the parent table was best represented by a set of radio buttons set to the side of the DataGridView. Turns out, there’s not a super-simple way to bind a radio button group to a column in a DataGridView.

I figured the easiest thing would be to populate the radio buttons from the corresponding column of the DataGridView when the user goes into a record, and to stuff the selected radio button value back into the column when the user moves away from the record. Do-it-yourself binding, pretty much.

Turns out, the Enter event works just great for the former. When I enter a record, the debugger shows the current value of my column in the underlying data source. Yay.

The latter is trickier. I tried using the Leave event, but that’s too late; my current row has already been shifted. I tried using the Validating event, but it didn’t pick up on the changed value of the radio button group either.

A moment with Google gave the answer: radio buttons within group boxes catch the Validating event of the containing box, not the of the whole form. Once I added a Validating event handler to the group box, my radio button values were picked up as current and properly saved.

There’s probably a really good reason for .NET to do this. sigh

The Single Most Effective Optimization

A year and a half ago, this really interesting scientific programming project more or less dropped into my lap.

The original code was written by a physicist–let’s call him Jim–who wasn’t a professional programmer but actually did an okay job writing and maintaining this Visual Basic Classic (pre-.NET) code for several years. “As a programmer,” someone might say in a gently mocking tone, “Jim’s quite a good physicist.”

So it’s cool. The important thing was to solve the scientific problem, and that it did. When I picked up the code with a mandate to get it working on a .NET platform and add a few features, though, I found it fairly hard to follow. A lot of the operations really needed to be event-driven but simply weren’t. There were a lot of modal dialogs and there were Windows forms with a ton of overlapping controls that got shown and hidden at various steps in the process.

So it was slow going, getting the thing to build and actually run on .NET. But the thing that saved my sanity in so doing was asking one simple question over and over again:

Does this code get used at all?

In many cases, the most difficult code was unmaintainable because nobody had to maintain it anyway. I consulted with the client, was told that the code implemented a feature that nobody used or even knew about, and simply deleted it. (After! Of course! Having all the originals under version control!)

There was a mishap or two in that regard, such as code invoked by menu options that seemed to be permanently disabled, but still. I could go back to version control (Subversion in this case), pull the original code back into Visual Studio, and massage it to get it to work.

But the massive reduction in workload caused by not having to work on 30% of the system at all more than made up for the few little problems. I’m pretty sure that the most effective development optimization of all, when working on legacy code, is simply cutting out the code that is never invoked or nobody cares about.