>I had a boss refuse to let me do a refactor that changed these sketchy dynamic field tables into json columns because “it’s not customer facing
YAGNI isnt about not refactoring existing technical debt. It's about not trying to pre-empt future requirements.
If youre refactoring in anticipation of as yet unmaterialized requirements then YAGNI applies - e.g. generalizing code when when today there is 1 specific use case because tomorrow you think there will be 3+.
If youre cleaning up existing code while working on it and the boss stops you because "it's not customer facing" then he's just asking you to violate the boy scout rule.
All of these definitions are fuzzy... refactor versus upgrade versus feature. When the people wrote it the way they did, they were almost certainly thinking that they don't need to overthink or over-engineer, and that they should discount hypothetical future concerns.
I can give you an abundance of examples. We were creating a page that was going to use state in a certain way. I was trying to insist that we address the way state will be handled across pages ahead of time. These concerns were dismissed as premature optimization. A few months later we had 5 pages with the state being handled in 5 different ways, and being synced in different ways between each page, complete with if statements, sometimes passing state through URLs, sometimes through local storage, sometimes through session, sometimes through JWT data, generally through a combo of several of them. Then we'd end up with confusing redirect loops for certain edge cases, state getting overwritten, etc.. We spend weeks fixing these bugs, and, eventually, weeks refactoring to manage state in a simpler way. These bugs often got caught by customers, drawing us away from feature delivery that was critical for demos to large customers.
All of that could have been avoided by spending 1 day thinking a little harder and planning for the future.
It ultimately boils down to a couple assumption that people like to make.
(1) engineers know nothing about the domain, they can never predict what will be needed. That might be true in a large company with obscure domain-specific things for engineers who work far away from the day-to-day, but sometimes the engineers know exactly what's going to come up. (2) You can hill-climb your way into optimal program implementation. You can get to local maxima this way, but there are regular ways that programs grow based on how the business is growing and you can predict certain places where you will soon hit diminishing returns for current implementations. As long as you're up front about it and double-check your assumptions about the way the business is growing (and hence the application), I think there are ample places where you actually are going to need it.
>I can give you an abundance of examples. We were creating a page that was going to use state in a certain way. I was trying to insist that we address the way state will be handled across pages ahead of time. These concerns were dismissed as premature optimization. A few months later we had 5 pages with the state being handled in 5 different ways.
The right time to address this was probably a bit at a time after the 1st, 2nd and 3rd pages. Certainly not before the 1st and definitely not after the 5th.
>All of that could have been avoided by spending 1 day thinking a little harder and planning for the future.
The reason why you try as hard as possible to avoid planning for the future is because it's really hard to predict the future. Moreover humans have an inbuilt bias towards thinking we are better than we are at it (hence the gambling industry).
Refactoring as soon as possible after the fact will always produce better designs than up front planning for this reason.
>there are regular ways that programs grow based on how the business is growing and you can predict certain places
This is the kind of phrase that makes alarm bells go off in my head that somebody SHOULD be following YAGNI and isnt.
If it's defaults in a well worn framework that doesnt railroad you then fine but anything more than that - red flags all around.
Rule of 3 is often correct, first time just do it, second consider if it'll very likely happen a third time and when the third time happens it's darn well time to do it!
HOWEVER, this only works if you have the agency at an organization to allocate time for doing something. Contrary to this when you are in an organization of management that doesn't understand technical debt (or is fine with it because it just means more consulting hours) then it's absolutely the correct choice to stall and/or fix things "prematurely" (iff you can see what product they are trying to create without knowing it) if you'll be holding the shit-can of duplicated crap down the line getting knuckled because things aren't going fast enough due to technical debt.
YAGNI isnt about not refactoring existing technical debt. It's about not trying to pre-empt future requirements.
If youre refactoring in anticipation of as yet unmaterialized requirements then YAGNI applies - e.g. generalizing code when when today there is 1 specific use case because tomorrow you think there will be 3+.
If youre cleaning up existing code while working on it and the boss stops you because "it's not customer facing" then he's just asking you to violate the boy scout rule.