Sunday, January 6, 2013

Propagating Best Practices in Code

Recently during a code review, I mentioned to my colleague that a certain method could be eliminated by just implementing the appropriate marker interface so our framework would run the equivalent code at the right time. Not having encountered that technique, he appreciated the comment and said “Is there an easier way to learn about what's available rather than through code reviews?” Good question.

I’ve noticed that within the context of a particular codebase, there are accepted best practices. In the previous example, the best practice was knowing what your codebase or framework already provided vs what you needed to write, but there are other examples such as which classes should begin transactions, how to get a database session, and using programmatic transactions vs declarative transactions.

As a software product is developed, the team develops a standard for how to accomplish particular things in code. But you know what they say: the nice thing about standards is that there are so many to choose from.

On a large project (say, 1+ million LOC) I’ve found that often one practice in code is improved or modified resulting in two ways of doing something (since the previous technique is not removed). This can happen again and again, resulting in multiple practices in the code. When someone who’s not familiar with that practice looks for examples, it becomes impossible to tell which is the “best” or “accepted” way to do something.

At first I thought of this as a refactoring problem. If only we had enough code reviews, such cases would be caught and older duplicate techniques would eventually be refactored away, right? But I think the issue is more general than that, that this is actually a case of methodological organizational knowledge being lost. People change jobs, people unknowingly duplicate effort, and with a large codebase it becomes difficult to propagate every practice or know what every other person is doing.

This raises some questions: How do we build up best practices or established ways of doing things in the code? If we want to update a practice, should we fix the old practice incrementally as we see it, or migrate it all at once?

For the first question: knowledge management is a well-known process. In the context of software development, I imagine that spreading knowledge would ideally include a variety of communication techniques such as code reviews, learning sessions, mentoring, and pair programming. Last on the list (but still on the list) would be documentation, since developers generally look to code for examples rather than static documentation.

For the second question, note that developers generally reference the code rather than static documentation. If we try to slowly migrate one practice to another, there is a danger of developers propagating the old practice. That is an argument for refactoring a practice all at once, but depending on the scope of that change it could carry significant cost and risk (that the old practice covered a case not covered by the new practice). So there is a balance to be had between incremental updates to a practice and migrating a practice all at once. To make the decision on that balance, I would say that if the refactoring is small enough to be accomplished in, say, a single sprint, then it’s worth it to refactor. Beyond that, the cost and risk may be too high. Such a change should be accomplished incrementally by changing the old practice as you come across it, and by noting this as a larger task in your backlog.

And hey, maybe sharing knowledge would best be done with tweets! "Hey I just started using ActiveButton instead of HoverableButton, you should use it too". Wait, that’s too many characters, it should be more lolcatz. "yo dawg i jus strted usin ActiveButton FTW! u shld use it 2! OMGLOL”

No comments:

Post a Comment