Designing code is its own task separate from implementing it. Not having a design--or having a fundamental failure of design--is, I think, what we really mean when we say code "needs a refactor". That is, refactoring code is re-designing code. Nobody ever refactors without some kind of design, regardless of whether that design has ever made it outside their head, let alone their subconscious.
So in order to refactor, we must first design. But when we design, if we have the wrong goal in mind, we can easily find ourselves doing more harm than good. Is it just me, or have we all had that time we took that block of ugly code and cleaned it up nice and proper, only to have a colleague later call the new code incomprehensible? And for them to be right, because it is?
So good design--intelligible design--matters. It matters a lot. And the wrong design--like the wrong abstraction--generally does more harm than good. So how do we know that our design is good? How do we know our design now won't ju