It takes time to build the kind of self confidence and humility it takes to allow a code base to sprawl for a while until you've seen enough examples to have an idea where it's going.
The first thing I like to do is solve the problem, period. Without inventing anything, just simply write code to cover most cases. Then I'll start improving on it in small ways, cutting down on duplication and inventing abstractions; until I reach a tipping point where I can visualize a complete design, which results in a major refactoring.
It looks messy in comparison to so called best practices, but it's faster and the code that comes out of the process is clearly better.
DRY is hurting more than helping if you ask me; because it shames inexperienced developers into premature abstraction, causing plenty of pain and misery along the way.