I think something similar happened with the term "refactoring." While it had been in use by a small community beforehand, Fowler's "Refactoring" book is what really opened it up to a wider audience. The book defines refactoring as:
"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs. In essence when you refactor you are improving the design of the code after it has been written."
The book then goes on to describe the methodology and runs through common refactorings step-by-step. Nowadays the term is used almost generically for code improvement. I'll see commit messages like "refactored the API", which violates the edict to not alter external behavior.
Languages evolve and so on, but it's remarkable to me how quickly precisely defined terms (or even new words) change their meaning in tech. My cynical take is it's easier to get management to buy into "assuming technical debt" and addressing it with a "refactor" later than it is to "cut corners" and "rewrite" the code later. As long as everyone understands the new definition I guess there isn't even anything wrong with it, but it's a shame we've then lost a term for the original meaning.
> Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
That's the meaning of refactoring that I typically hear, tbh.
I guess it just depends on what one means by "external behavior". Changing a function signature changes the external behavior of that function for callers of that function, but not for other modules. Changing the interface of a module changes its external behavior for other modules depending on it, but not for clients of the whole server. Changing an API changes the external behavior for the client, but not for the end user (to whom API changes are invisible and irrelevant).
Traditionally, one might say "if the tests still pass, it was a refactor." Though nowadays that's probably not true either, as business code tends to contain a lot more internal testing than it used to (which is good! but also bad).
Perhaps my initial selection was too short. I was trying to avoid copying out whole sections of the book. Overall, I think the book is less ambiguous than the one definition I presented shows. The entirety of the text reinforces different aspects of that definition.
Fowler goes on to elaborate on the definition in chapter two, where he presents two context-dependent definitions (one a noun, the other a verb). The noun form is a specific type of change and the verb is the application of one or more of the nouns. E.g., "Move Method" and "Move Field" are types of refactorings. These are defined as changes made "without changing its observable behavior." To further qualify, he states "[o]nly changes to make the software easier to understand are refactorings." By way of example, he compares to performance optimization where he says: "A good contrast is performance optimization. Like refactoring, performance optimization does not usually change the behavior of a component (other than its speed); it only alters the internal structure."
Maybe it's just the domain or languages I work with. Nowadays I never see anyone apply refactorings as described in the book. I'm sure devs implicitly apply several of them, perhaps without the rigor presented, and that's understandable. But, I often see "refactoring" just as a catch-all for any code change.
While certainly there are some blurred lines in terms of what constitutes a refactoring or not, I think Fowler handles the product/API split fairly well. He adds:
"The second thing I want to highlight is that refactoring does not change the observable behavior of the software. The software still carries out the same function that it did before. Any user, whether an end user or another programmer, cannot tell things have changed."
By stating a programmer should not be able to tell things have changed, I think we can at least anchor public APIs as something that should not be adjusted in a refactoring. Such a change could improve the maintenance of the software or the quality of the product, but I don't think it fits the narrow definition of a refactoring. Admittedly, the part about the observable behavior of the software not changing can get murky. But, I think Fowler tries to scope this more at the code level than at the product level.
"Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs. In essence when you refactor you are improving the design of the code after it has been written."
The book then goes on to describe the methodology and runs through common refactorings step-by-step. Nowadays the term is used almost generically for code improvement. I'll see commit messages like "refactored the API", which violates the edict to not alter external behavior.
Languages evolve and so on, but it's remarkable to me how quickly precisely defined terms (or even new words) change their meaning in tech. My cynical take is it's easier to get management to buy into "assuming technical debt" and addressing it with a "refactor" later than it is to "cut corners" and "rewrite" the code later. As long as everyone understands the new definition I guess there isn't even anything wrong with it, but it's a shame we've then lost a term for the original meaning.