My two cents for such and old question
Some people already mentioned, practice and refactoring. I believe the right order to learn about patterns is this:
- Learn Test Driven Development (TDD)
- Learn refactoring
- Learn patterns
Most people ignore 1, many believe they can do 2, and almost everybody goes straight for 3.
For me the key to improve my software skills was learning TDD. It might be a long time of painful and slow coding, but writing your tests first certainly makes you think a lot about your code. If a class needs too much boilerplate or breaks easily you start noticing bad smells quite fast
The main benefit of TDD is that you lose your fear of refactoring your code and force you to write classes that are highly independent and cohesive. Without a good set of tests, it is just too painful to touch something that is not broken. With safety net you will really adventure into drastic changes to your code. That is the moment when you can really start learning from practice.
Now comes the point where you must read books about patterns, and to my opinion, it is a complete waste of time trying too hard. I only understood patterns really well after noticing I did something similar, or I could apply that to existing code. Without the safety tests, or habits of refactoring, I would have waited until a new project. The problem of using patterns in a fresh project is that you do not see how they impact or change a working code. I only understood a software pattern once I refactored my code into one of them, never when I introduced one fresh in my code.