Tuesday the monthly Agile Tuesday took place, my first one. Thanks to Mario Gadet who invited me a long time ago and made sure I didn’t forget about it. Already this put the bar quite high for me and I was quite nervous about it because I didn’t expect the typical tech audience. And it all turned out different than expected :).

Refactoring hands-on

I talked a bit about refactoring. I tried to summarize the hows and whys for it in order to get to the doing, right after the talk. And I picked the beautiful Tennis kata to refactor some stuff where some interesting things evolved.

We did it mob-style. The mob, the entire audience, told me what to do. The only thing I did, was asking questions or trying to deal out who is next, when the amount of input came too fast. So I typed using WebStorm, which made some people be astonished about what is already possible with this IDE in combination with JavaScript. The tests ran automatically so we never left the green state for too long. Thanks to the crowd I got reminded a couple of times to do, what I had suggested in the talk before, use Ctrl+Z to undo changes.

And while at it we made a couple of interesting discoveries, let me share some with you.

The Evil of Native Constructs

A very interesting discussion spun off when we refactored the following switch

into this array

The valid arguments raised were that the explicitness of the `switch` gets lost in an implicit use of arrays, they are zero-indexed and therefore implicitly do the same as the switch, but it’s not “visible” as well as in the code before. From there we started discussing how much the source code shall rely on language specific constructs. Shall a piece of domain knowledge, here the mapping of 0 points to ‘Love’ and 1 to ‘Fifteen’ and so on, be hidden behind an implicit construct that actually does the same and allows for less code, but also reveals the intention less good?

Which raises a new question: what is the minimum level of language-specific knowledge required for the code to be maintainable, also by non-seniors? It’s just a fact that there is a gap in knowledge between the original author, the team and/or the future maintainers of this code. Should therefore the code be written by using less “difficult” constructs? Maybe even prevent certain language constructs that might cause traps?

I doubt that this helps. Depending on the domain the code is written for the code has to adapt. If the mapping of 0 to ‘Love’ and 1 to ‘Fifteen’ are core concepts of the business domain we are in, make those concepts clear to the (future) maintainers by writing more explicit code.

Artificially reducing a programming language’s feature set which sometimes just prevents that others have to learn new things, feels also very counter-productive and almost like trying to slow down evolution. A programmer just has to learn, constantly.

This led to an alternative construct we used, which makes the domain-level view more explicit. We write the relation between the numbers 0,1,2,3 and the according strings explicitly into the source code. We are not using a switch-case though.

The object-notation will be accessed just in the same way as the array above via `pointsMap[points]`. All participants have been really happy with this solution. So we all agreed to keep on moving forward from here.

Since JavaScript is an interpreted language the obligatory speed discussion came up. Is object creation and access not much slower compared to array creation and access? But that discussion stalled quickly, due to irrelevance. And I was happy about that, because if this is our hot path then we will find that out, but for now the better code has way more value.

Tie Scores

A little bit later we touched code that looked something like this:

The mapping is very much like the one we handled above, but has a little twist to it, which is the case for all values from 3 upwards. First thing the crowd decided to do is move the map out of the function.

Then we tried to reduce the actual function down to this.

The decision to remove the `if (points < 3)` was actually pretty easy. We said that this can be done implicitly by looking up if there is a value defined for the given number of points. Some people liked it some not. It is a very JavaScripty solution, but actually very common in JS land. Those are the kinds of discussion I love at non-JavaScript events, they always provide me with different views. It went a bit forth and back. The disadvantage of the latter solution is that you have to look up in two places to completely understand what the function does. You have to know what is defined in the `pointsMap` or you won’t understand when the ‚Deuce‘ is returned. Another critique was that the string ‚Deuce‘ is in the function, but all other strings are in the map. Finally we tried something a bit unusual, we moved the `Deuce` string also into the map and changed the function to look like this:

And the crowd was happy, I mean really happy, it seemed.

Conclusion

The discussion about explicitness led us to use an object instead of an array. If this hadn’t taken place we would never have seen the solution with the elegant `default` key in the object.

Doing all that in a mob-style fashion, which means discussing in the group and having one person execute the solution that had been agreed upon, is always again a fun experience and makes people engage and steer towards a good solution together, learning to accept opinions and find one (of the) best solutions.

Can we help your project?

We love to discuss code and tests, build strategies and help improving things. If you think this is something that should be done in your project/company/department please contact us! We are happily offering support and love to share our knowledge.

You can also find us at various events, we are always curious about learning new things and helping out if we can.

Sugar cubes image source