There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.
The problem with simplicity is that it can be awfully complicated to get there. I have often found that when thinking about a problem I start with a solution that is simple, but naïve (and wrong). As I continue working through the problem I get cleverer and cleverer but more and more complicated. If I stick with it for long enough I continue to get cleverer and cleverer but get less and less complicated until (if the programming gods allow) I end up with a clever, but simple, solution that is also correct. I need to remember to have the confidence and patience to get over the hill to the simple solution.