Several days ago, we had a coding dojo at Digital Natives: we wanted to reimplement a method without changing its purpose. To do this, we used a technique called building a bridge, which is also known as parallel change. The technique itself is quite simple, and in this post I’m going to show you how to use it and why.
For example, I have this piece of code, which is presumably part of a larger code base:
class Foo # ... def count(first, last) counter = 0 first.upto(last) do |i| counter += 1 if prime?(i) end counter end private def prime?(value) [2,3,5,7,11,13,17,19].include?(value) end # ... end
Maybe it is not working very well - its limitation is obvious -, but it is more than enough for now. Let’s say that we decide to change the prime? method. The same method, the same purpose, only the algorithm will be different. So we create a new method called prime_next? and implement that method either with TDD or in a regular fashion. After it is done, we’ll have something like this:
class Foo # ... private def prime?(value) [2,3,5,7,11,13,17,19].include?(value) end public def prime_next?(value) # a fancy algorithm probably based on Fermat's primality test end # ... end
When our tests or gut feelings indicate that the new method is complete, we replace the method names, so prime? will be come prime_next? and prime_next? will become prime? (hint: it is easier and safer to switch the actual method names than to change the references. For example, in ruby we don’t have a fancy IDE with the “rename method...” functionality so it would take some time until all the references are changed, not mentioning the expressions evaluated at runtime).
We run some more tests - or trust our feelings - so that we see whether the new algorithm is working with the rest of the code base. If everything is up and running, we clean up and deliver:
class Foo # ... def count(first, last) counter = 0 first.upto(last) do |i| counter += 1 if prime?(i) end counter end private def prime?(value) # a fancy algorithm probably based on Fermat's primality test end # ... end
This was the “how”, but it seems a lot of unnecessary work for a change, doesn’t it? It may seem like that at first, but I prefer to do it, because it ensures that while I’m working on my changes, I can still work with the rest of the team, and that the code I’m working on is well tested. Now, let’s see the “why”.
There is a reason why this technique is called building a bridge. Have a look at the picture below (source: http://www.transportation1.org):
This is how wise men build a bridge. They start building the new bridge (
prime_next?) on the left side next to the old bridge (prime?) on the right, so that the traffic won’t stop until the construction is finished. When it is finished and tested, they stop the traffic for a single moment - compared to the construction time of the new bridge -, connect the new bridge, open the traffic there and close down the old bridge. As easy as pie. Imagine what would happen if they just demolished the old bridge and started working on the new bridge: traffic would be stopped for very long time.
The traffic is the most important element of this metaphor. It represents my workflow inside my team. The moment I change anything inside the prime? method
I cannot commit that change until it is finished (maybe for days)
I have to merge every change the other team members may do on prime?
I lost the security nest provided by the global test harness
No continuous integration, no static code checkers, no external help
and the list goes on. If my changes are separated from the original code base, I can commit, run the test cases, and get feedback on my changes. The only thing I shouldn’t forget is to clean up - to demolish the old bridge.
There is another angle worth mentioning here: the limited red society from Joshua Kerievsky. According to Joshua, we should spend as much time in green as possible and limit the time spent in red. This will ensure that we implement the right thing correctly. If I start implementing the prime_next? method, I’ll have the healthy red-green-red-green TDD rhythm until I’m finished, but the important thing is that the original part of code base will always be green. The switch between prime? and prime_next? will cause a tiny little time in red at the end, but if I started with the prime?, I would spend all my time in red, which is unhealthy, believe me, or believe Joshua.
The building the bridge technique also comes in handy when I want to implement a fake functionality (I used the word functionality on purpose, because it can be a module, a class, or a method. I’m using methods in my examples, because they are short). For example, I had the following method - own_random - faked while I’m doing TDD:
class Foo # ... def foo value = result_of_a_lot_of_other_things * own_random end def own_random # temporary fake return 3 end # ... end
When I’m done with the other parts of the code, I can start working on the fake method: own_random. More precisely, on its new implementation: own_random_next:
class Foo # ... def own_random return 3 end def own_random_next # my excellent new random algorithm end # ... end
Until the new implementation is ready, the test cases which depend on the original own_random implementation will pass, and so will the new test cases of the own_random_next method: I’ll spend only a limited amount of time in red. Well done. The rest of the steps are the same as described before, so if you don’t mind, I won’t repeat them here again.
I really like this technique, because it is easy and pretty straightforward to use, plus it saved me a lot of time in the past. I hope you like it, too.
comments powered by Disqus