reflective software development, as a service

Menu

Connascence of Value: a different approach

Recently I wrote a series of posts in which I attempted to drive a TDD episode purely from the point of view of connascence. But as I now read over the articles again, it strikes me that I made some automatic choices. I explicitly called out my design choices in some places, while elsewhere I silently used experience to choose the next step. So here, I want to take another look at the very first step I took.

You will recall that in making the first test pass I introduced some CoV (Connascence of Value), because the test and the Checkout class both know the magic number 50:

I fixed that CoV by passing the magic value as a parameter, following the Dependency Inversion Principle. But there are plenty of alternatives. Instead of using the DIP, I could directly convert the CoV into CoN (Connascence of Name) by introducing a constant in the Checkout class:

(This isn’t something I would do in real life, but let’s just see where it leads, for curiosity’s sake.)

That was a really simple step, and it completely fixes the CoV: CoN is level 1 on the connascence scale, and is thus the weakest kind of coupling I could have. Note that I can no longer use random values in the test; I wonder where that fact will lead…

As before, I am now left with CoM (Connascence of Meaning), because both the test and the Checkout know that monetary values are represented using an int. I fix that in the same way as I did last time, by introducing a Money class:

As before, I have to add a few useful things to Money to get this to compile; all good. But this time around, it seems I have more choices when it comes to getting the test to pass. That’s because I fixed the CoV with a constant, thus imposing less structure on the Checkout.

For the sake of similarity I will do the same as last time (even though I know it causes problems later). So I calculate the running balance inside scan():

That doesn’t change much, but those constant names are interesting. I feel they are tied to the SKU strings somehow, and that makes me uncomfortable. Then I see it: I have now introduced some new CoV, because the name PRICE_OF_A depends on the value of the string “A”. If either changes, the code will not break, but my head will. All of which means that the introduction of the constant for the price of B didn’t really fix the CoV; it just moved it around a bit!

I guess that means I have to fix the CoV of the SKU names in order to make any progress. Let’s just take a moment to look at the extent of this coupling:

The SKU name is known in three places, each of which is coupled to both of the other two. So in order to fix this CoV, I have to move that value into exactly one place.