Have you ever tried to provide design for Mark IV coffee maker problem that Robert C. Martin presented in his "Designing Object Oriented C++ Applications using the Booch Method" book. Well I have and I was not successful to come up with any kind of elegant solution. But I was quite impressed with the solution that Uncle Bob presented for this design problem. You can find the solution here.
What I find interesting in the above document is section titled "How did I really come up with this design?". In that section Uncle Bob says:
I did not just sit down one day and develop this design in a nice straightfoward manner. Indeed, my very first design for the coffee maker looked much more like Figure 11–1. However,I have written about this problem many times, and have used it as an exercise while teaching class after class. So this design has been refined over time.
This paragraph was very encouraging to me, because as you see even Robert C. Martin himself did not get it right the first time. We are not going to get it right the first time, no matter how much we try. Good designs come over time, they are not obvious immediately. Our initial design will change over time, and we need to ensure that changes that happen will lead to better design. I see great power in refactoring here. By doing refactoring we change design of our software to something better and still preserve clean and maintainable code. Unit testing and TDD in general is of great help here as well. It is the immediate feedback that makes us less fearful of making changes to our code.