Code Refactoring with Parameterization
Update (13 July 2017): I fix the wrong weight average logic in the code and also provide a working example that you could run on your machine. :awesome:
There are multiple occasion that I came across an ‘almost similar’ chunk of codes all over the code base. The problem with this kind of code smell is, once you want to change just a tiny bit of that particular function, you need to find all the implementation you did and change all of them which is not a good idea.
Duplicate code is a major cause of unmaintainable scripts.
— Brian Marick @ Everyday Scripting with Ruby
The technique that I often use and find it’s super easy to do is parameterization. Today I’ll explain how that works by a nice little example.
Finding weight average
There are reports that I need to find a weight average of a gross profit field and they are going to be weighted by sale revenue. Here is what I came up with. (in Ruby)
Simple stuff right? Now we need another method that does this exact same thing but for another field called cogs. The easiest thing here is to just duplicate the method and change what’s need to be changed.
Make it work, then make it right ❤
We got what we want right? Cool but what if we need weight average of other stuff? What if we need to change the weight from sale_revenue to something else? Creating new method that shares this logic would lead us to the problem I was talking about earlier., the duplication problem.
Parameterization in action
Now what do we see, these two methods is almost identical right? The only different is the block I passed into the map
function.
Extract the similar codes out and put them in the new method. I’ll call it w_avg
then parameterized the differences.
Notes: Ruby can dynamically calls a function by passing
string
orsymbol
to the methodsend
I’ve remove the duplicate method now and our program look like this.
Now the logic of these two methods are in the same place. I can easily extend it to compute a weight_avg of any value from the report with a one-lined function.
Here is a link to a working version of this Ruby program
Download it and run it by
ruby parameterized_working_example.rb
Going further
Parameterization is a nice little trick but it is not a silver bullet. Sometimes it is wiser to have small amount of duplications than one over abstracted method than cannot be extended or modify. As Sandi Metz stated in RailsConference 2014
Final Note
I believe we should focus not only on making things work but also on creating a clean code base that can be easily maintained by any developer carry on the project.
If you have any questions or suggestions, feel free to comment them down below and please hit that little green heart to give me a pat on my back.
Thank you for reading
My name is Tino Thamjarat. Technical Lead at BASE and Software Engineer at Oozou . I love discussing everything. Business ideas, philosophy, physics, religion, tech, gaming, you name it. I also play League of Legend and a little bit of music once in a while. If you need a website, want to give some advice/comments or just need some guy to talk to, feel free to contact me on my Twitter or Instagram.