Over-Abstraction
Smell. Machinery with one user: a trait with a single implementation
and no test double, generic parameters only ever instantiated with one
type, a Box<dyn Strategy> choosing between two behaviors that an if
could choose, a factory that builds one product, layers that only forward
calls.
pub trait FrameSourceFactoryProvider {
fn factory(&self) -> Box<dyn FrameSourceFactory>; // builds one thing
}
Why generation produces it. Abstraction is associated with good engineering in the training data, and “make it extensible” in a prompt is taken literally. Unlike the other smells, this one comes from trying to do well.
Principle. Abstraction is a bet on future variation, paid for now in indirection. Every layer is another file between the reviewer and the behavior. The decision procedure from Flexibility in Signatures applies: closed set, use an enum; genuine extension point, use a trait; otherwise, write the function.
Prompt. “Remove speculative abstraction: inline traits with a single implementation unless they are a test seam or a documented extension point. Replace the strategy objects with an enum, since the set of variants is closed. Collapse layers that only forward.”