After ~5 years of real-world experience I've become so much better than I used to be at software design. Interfaces, dependency injection, small classes, composability, factory methods, generics, micro-optimial algorithms, etc. However I'm not sure I have become faster at delivering work items. It used to be that someone gives me a business problem and I could whip out a solution that works, although my code was "bad." Now it takes me the same amount of time, but my code has 100 layers of abstraction over the concrete business problem. This is all very "good" code as it can be justified with "We can easily swap out some dependency and it will still work," but I question whether this future-proofing pays off on average.