Improving code traceability with contextual mutations

Improving code traceability with contextual mutations

Mutation is common in the world of business logic. Take StackOverflow as an example: a user can create a question and later change its content. However, when this concept is translated into the programming world without careful thought, it can lead to issues that affect maintainability, particularly in tracing mutations in the codebase.

Let’s consider a super simplified example of a fictitious StackOverflow clone. Imagine a REST API endpoint that allows the user to update their question:

Article content

In this example, updating the question's description requires mutating a public description field. This might seem straightforward, but imagine a codebase where this field is mutated in many locations. With multiple files editing this description field, various data sources updating the Question description, a codebase with 50k lines of code, and numerous other classes also containing a description field, how would you locate where the description of a Question is updated? Here are some approaches:

  1. Search for the term ".description =" (which could be improved with a regex search).
  2. Find all references for description of the Question class.
  3. Find all references for the functions that persist updated Question data.

Let’s review each method and its drawbacks:

  1. Search for the term ".description =": Multiple classes have the description field, leading to a large list of potential candidates. Additionally, variations in spacing (like ".description=" vs. ".description =") can complicate the search.
  2. Find all references for description of the Question class: This will include both mutations and queries of the description field. Queries are often more frequent, resulting in a long list of possible candidates.
  3. Find all references for functions that persist updated Question data: While this identifies the files where question info is updated, the actual mutation might be hidden inside nested functions, making it difficult to locate the specific ".description =" line.

Ultimately, these methods of finding where the description of the Question class is updated are not specifically designed for this purpose. Fortunately, there are some refactors we can implement to improve traceability. The first refactor involves encapsulating the mutability of this field in a single function, such as a setter:

Article content

By searching for references to setDescription, we can precisely locate all the places where this field is mutated. While this approach solves the problem, it lacks context about why these mutations occur, which would be beneficial for understanding how our business rules align with our codebase. Here’s an enhanced approach:

Article content

Now we can clearly understand the context of these mutations and accurately represent the business rules. Of course, in a realistic scenario, there would be more data, code, and other classes involved in these mutations. However, adding context to mutations remains viable and significantly enhances the traceability and maintainability of our codebase.

To view or add a comment, sign in

Explore content categories