TDD and Intentionally Violating the DRY Principle

Anyone that knows me knows that I’m a huge fan of TDD. Not just TDD for testing - but TDD for architecture (and many other things too).

I’m currently working on a project where I generate a lot of pdf documents. I had a couple of big-picture ideas for how to write the code, but there were a few things that I knew would emerge and become clearer as I starting writing the code. When we finally picked a pdf-library for the document generation I quickly found out that the API was horrendous. There were areas that this significantly complicated the “ideal” architecture for the application (at least the way I had originally envisioned it).

I didn’t try to do much BDUF (intentionally), so I figured I would just let the code and the circumstances tell me what to do and this pretty much how it went…

  1. I wrote the implementation for the drawing (the api I’m using is based on a nasty coordinate system used for generating pdf files) of the first document.
  2. I wrote the implementation for the drawing of the second document, and the third document, and the fourth document.
  3. I noticed that I was duplicating a *lot* of code (it was nasty code too).
  4. Since I had tests around everything, I figured I could easily refactor and remove the duplication. Unfortunately, I couldn’t figure out how to refactor the duplication out to something clean. At this point, I got a little worried. I typically like to remove duplication as soon as I notice it. I had a lot of duplicated code in three different places and to say the least — I hated knowing that it was duplicated. I wasn’t sure of what to do so I kept duplicating code. The code that was being duplicated wasn’t one-for-one, but it was close enough that it was obvious that at some point it should by consolidated and reused.
  5. I wrote the implementation for the fourth document.
  6. I started to see some common patterns where I could start to pull out the duplication.
  7. I wrote the fifth implementation.
  8. I had a good weekend.
  9. I started refactoring and was finally happy (thank god for tests).

I usually follow the red-green-refactor cycle but in this case I just wasn’t sure how to refactor. After lots of duplication and more experience I learned more about the API that I was using and this allowed me to refactor back into code that *felt* right. I still have some duplication, but I’m sure as I write a few more implementations that the duplicated portions will work themselves out like the other duplications did.It’s interesting, because I would usually have recommended to remove the duplication at the first (or second) sight of the repetition.

2 Responses to “TDD and Intentionally Violating the DRY Principle”

  1. Michael Says:

    So, assuming that this was the project that you used Agile Modeling on, how did it work out? Was the duplication something that was a side effect of the Agile Modeling or was it just becase of the exposed API from the PDF creation tools that you were using?

    BTW, what was the artifact that you used for the modeling? Use cases? User Stories?

  2. Ben Says:

    It was the same project. I think it was mostly because of the API and my lack of familiarity with the product. The API has multiple ways to accomplish common objectives, so I wasn’t initially sure of the best way to wrap up the API with something that was a little easier to use.

    As far as the artifacts go, I used user stories. I like the format of stories much better than use cases.

Leave a Reply