How are We Infusing Effective Code Quality Practices: A Large Software House Case

Change is inevitable and difficult!  Software systems are expected to evolve continuously to meet the ever increasing demands of its users. At the same time, the intangible nature of software makes it difficult to manage this continuous change, resulting in poor software quality and larger technical debt.

This is so relevant for any organization! Design and code smells are a common problem everywhere and especially in teams that deal with legacy code. Software design is a complex activity that requires the combination of knowledge, skills, and the experience to provide a high-quality solution.

For a typical product-based company that has products in the market for a number of years, it is more challenging (given the long life of the legacy products) and sometimes becomes a herculean task to add new features while not impacting the existing functionality. The knowledge and awareness of technical debt and design smells definitely bring in a new perspective of looking at the code and ponder about refactoring smelly code that has been residing since long.

I got introduced to the concept of design smells in a training that was conducted within the company almost 3 years back. I could relate instantly to the examples that were being shared by the trainer, which indicates how common the design problems are. The trainer recommended the book “Refactoring for software design smells: Managing technical debt” which is a masterpiece in itself. The simple language, the anecdotes, the real-life use cases, and illustrations make the book more understandable and relevant. It is definitely a bible for developers and architects. Software refactoring has always been a painful and risky task, but the simplicity and effectiveness of the refactoring techniques mentioned in this book have encouraged teams to pick up refactoring tasks as a part of their daily development cycles. This has helped address the long pending technical debt and lay a strong foundation for the fresh code that is written.

Ever since my exposure to the concept of design smells and their refactoring techniques, I have been trying my best to be involved in the refactoring activities and apply the gained knowledge. I also strongly believe in spreading the knowledge and therefore I volunteered to take this further and share the knowledge with as many colleagues as possible. With the help of a few managers in the organization and support from a couple of colleagues, we have been conducting training sessions and spreading awareness about design smells and how to deal with them. Collectively so far we have conducted sessions for 150+ people (and counting) within the organization.

It is commonly observed that there is a lot of hesitation, perhaps even fear to touch an existing piece of functionality which is working even though it is really in a bad state. In order to curb this hesitation and fear and to encourage refactoring, we stepped up, devised, and experimented a special 3-weeks program which was focused on applying the knowledge gained about design smells on real code. We follow the program given below.

  • In the first week, we deliver the training on design smells and corresponding refactorings to a batch of developers.
  • We then handpick a few of them and groom them on these topics.
  • These developers use some of the available tools for identifying smells in their code.
  • Once the smells are identified, we identify a few smells which appear in critical areas with the help of their respective architects and then we target them to fix.
  • Before we start the refactoring activity, we make sure that existing test cases are passing on the existing code.
  • The next one and half weeks are dedicated to refactoring the code to eliminate the identified smells. This involves a lot of discussions with the developers, their team members, and architects.
  • Once the refactoring is complete, the code is peer-reviewed.
  • We ensure that the existing test cases are passing, thus validating that the underlying functionality is unchanged.
  • Towards the end of the third week, the developers are asked to prepare a case study about this exercise and present to the team.

The outcome of these presentations were so far really satisfying. We observe the following outcomes in general commonly.

  • The code gets more structured and modularized. It becomes more understandable, simple, and most importantly – it becomes more testable.
  • The number of test cases go up considerably as the developers could write tests which were not really feasible due to the coupled structure.
  • The confidence of the developers about their own code increases and they seem happier, satisfied, and motivated with this exercise.
  • The developers also present the same findings to a larger group from top management. The entire effort gets a welcoming response from the management.

Our aim is to take this training and mentoring program to each team within our organization and encourage them to understand technical debt and start refactoring their pending complex pieces of code.

Earlier, these sessions were planned only for senior developers and budding architects. However, with the success of the above program and a very positive collective feedback from all our ex-participants, we have now expanded the scope for these sessions and are planning to include this session as a part of the company-wide annual internal training program. We strongly believe that this will help shed the inhibitions about code refactoring and will encourage more people to take care of their code quality more effectively.