Maybe the most astonishing thing I've learned in my career is that it's far better to design your system after the code is written and working!
Because that's the time when you've learned to understand the problem, and you already have working code to move around.