Patterns are indeed very useful, but I would caution against using them as a starting point for learning how to design software. I have seen far too many "over-engineered" software designs where the designer has thrown in every idiom and pattern he could think of, assuming that "more" is "better".
My suggestion for learning how to design software is to start with a few basic principles, and try to build the simplest solution you can which meets your needs right now.
To do this, it's vital to understand what you
actually need. The best way I have found of ensuring that I understand a need, is to try and write a
test case for it. Writing a test case, especially an "executable" test case (a program which calls your code and checks the results), really helps me to "bottom out" any remaining misunderstandings.
When I have a test case for a new need, I can then write the simplest code I can think of to pass the test. Then look at my new code in the context of the rest of the system, and remove duplication wherever I find it, to simplify the whole thing.
Repeating this process (understand a need, write a test case, pass the test, simplify the system) should result in a well-designed solution with no unnecessary code.
Where experience in designing software can help is in recognizing un-needed complexity, and in knowing how to simplify it. Systems produced by inexperienced designers almost always have more code, more complexity and more "bugs". This is where things such as patterns can become useful. Patterns can be like "canned experience", but the most important thing is to study when to use (and when not to use) each pattern.
If you are just starting out in design, recognize that your initial designs are bound to be larger, more complicated, and therefore more "buggy" than they really need to be, but don't despair. Keep coming back to each system and simplifying it each time you learn more, and the practice will lead you to designs to be proud of.