Philosophy and Design
Non-blocking refactoring
Bronto takes a "non-blocking" approach to code transformation. Let's explore
that idea with a simple example of renaming a function. A classical "blocking"
approach would be to change the name of LegacyFunction
to NewShinyFunction
,
and then go find all of the callers of LegacyFunction
and update them as well.
This approach is "blocking" in the sense that you must find and replace every
reference to LegacyFunction
before the code will compile again. In other
words, uses of NewShinyFunction
must wait until all references to LegacyFunction
have been changed.
Consider a different four-step approach.
Create a copy of NewShinyFunction
with an identical body to
LegacyFunction
.
Update the implementation of LegacyFunction
to simply call
NewShinyFunction
.
Replace all calls to LegacyFunction
with the body (the call to
NewShinyFunction
).
LegacyFunction
.Notice that immediately after step 1, NewShinyFunction
is usable. You don't have to complete the entire refactor before users can gain the benefits of the new feature, no matter how many callers LegacyFunction
has. Moreover, Bronto automates step 3 so it can happen in the background. After Bronto finishes step 3 across all your callers, codebases, and dependencies, you can come back and handle step 4.
Intent as source code
The non-blocking approach to refactoring can tackle much larger
refactoring problems than a blocking approaches allow. It gracefully handles other developers making simultaneous changes (potentially even
adding new usages of LegacyFunction
!). It handles these new changes as they are added, by recording the intended refactoring directly in the code, so it can be seen across repositories and centrally administered. This is the key insight for Bronto's overall design.
The changes you intend for your codebase should be a part of your codebase.
Rather than living in a developers brain or IDE, intended refactorings should be tracked in version control. Allowing engineers to understand not just the current state of the codebase but where it is headed and how that direction has changed, all with commit messages explaining why.
This stronger model for refactoring applies normal development practices to refactoring problems. Allowing automation to manage much larger refactorings than traditional approaches that lack a central source of truth.