Programming literature is rife with "thou shalt not" commandments, which produces an image of having to be some genius who always gets these things right the first time; but actually trying to follow all of them all the time will make you a scared and confused programmer, overarchitecting in various ways to push problems away from the surface, which - most of the time - only ends up adding brittleness and doesn't solve the actual problem. Similarly, there's always some uncertainty about trying any new technique or technology, which can only be resolved by putting it into practice.
Most applications today need mostly "sweat" code(UI, all the various feature behaviors, integration of outside assets and APIs) and a tiny amount of "clever" stuff. Serious problems with architecture or performance tend to only reveal themselves once you've integrated a sizable number of features and they start tripping over each other. So the best way to actually reach the real problems tends to be to code like a madman until the problem finally reveals itself, at which point you can stop to think about it and do the necessary maintenance to set things right. Once you've done this enough, you gain domain knowledge and can actually plan farther in advance. Until then you are kidding yourself.