Following the initial post on the Importance of software craft at Goldman Sachs, this blog post covers an important aspect of software quality and its commercial impact on software development and delivery: deleting unused code.
We are focused on client happiness as reflected in our commercial software delivery of features, risk reduction, operational efficiency, and continuous delivery. There is a correlation between client and developer happiness; our clients are happy when they see regular enhancements to the software they use, and developers are happy when they're able to deliver software quickly. One aspect of developer happiness is healthy codebase and one of the key factors contributing to healthy codebase is code relevance, and this in particular is the subject of this blog post. Maintaining a healthy and relevant codebase is one of the important software craft practices that we follow.
One way to maintain code relevance is by identifying and deleting unused code. This can streamline our codebases, making them easy to maintain, and can improve our ability to deliver commercial benefit to the organization. We come across examples of unused code, often not realizing it. Such unused code convolutes the codebase - especially true to developers reading the code for the first time. They have to exert unnecessary cognitive load when trying to understand the code's functionality. Unused code directly impacts commercial aspects of software delivery, as having to manage and maintain irrelevant code will impact the team’s velocity and their ability to respond to rapidly changing business requirements. There are other negative byproducts of irrelevant code including unnecessary increases in build pipeline times, increased difficulty in library upgrades, and the inability to efficiently refactor.
During a recent software project, we were able to reduce the size of a codebase by 67% by adopting a set of practices that the remainder of this blog post will cover.
In the above diagram we show a continuum of lower effort to higher effort activities to help improve code relevance. They can be employed in stepped progression or be considered maturity levels. First, using IDEs and build dependency analyzers. Next having conversations with users and clients to diagnose their needs and the APIs and Flows that are not needed. Then, use Sonar and other static code analysis tools to identify unused code. Finally Identify unused API endpoints with custom observability mechanisms to ascertain detailed metrics on timings, users and responses.
Using this approach we accrued several benefits:
Uplifting components and dependencies became easier with a reduced codebase. As an example, we had some code tightly coupled to an older external library. Once we removed that unused code, we were able to upgrade to a supported corresponding version of that library.
We want to ensure that we keep our codebase relevant going forward and have adopted some practices and behaviors to support that. We regularly review and discuss observability metrics exposed by our applications. This allows us to have meaningful discussions with our clients about usage and deprecation. Static code analysis tools are integrated into build pipelines. This helps us identify duplicated and unused code. Our build pipelines also have a set of control gates, including build breaks, which help us maintain the quality of our software. We continuously review the code as a part of our software development practices, which involves discussions around new implementations, refactoring, and bug fixes. This review step helps us identify potential code duplication at an early stage.
Although identifying unused code and subsequently deleting it looks straightforward, there are a few considerations to be aware of. For example, if the code is executed through configuration (or reflection in the case of Java), it may look like unused code at first glance. Another example would be a transitive dependency on the component or module of a 3rd party library. Deleting the code in such situations is not feasible, however, we can take an incremental approach where we would deprecate the component first and provide the alternatives before removing it in the subsequent major version release.
Deleting the code is not always easy and is often met with resistance. However, fostering a Software Quality culture across the team really helps maintain a healthy codebase. Each software component that we write and manage has its own lifecycle, given the constantly changing nature of our industry. Maintaining a healthy codebase means one of the software component lifecycle stages needs to be ‘delete’.
Our clients are happy when we deliver reliable software regularly, and our developers are happy when we can see that we are contributing to the business as well as codebase hygiene. We believe the investments made in ensuring code relevancy result in significant commercial benefits to our business.
In the next entry in this series on Software Craft, we will focus on the code review practices at Goldman Sachs.
To learn more about opportunities at Goldman Sachs, we invite you to explore our careers page.
See https://www.gs.com/disclaimer/global_email for important risk disclosures, conflicts of interest, and other terms and conditions relating to this blog and your reliance on information contained in it.