Personally, I have learnt a lot by learning
a) Design
patterns
b) Downloading sources from Open source projects and debugging through them
I like to make an analogy with learning how to cook. When you start cooking, you first learn the basic concepts:- what are the various kind of ingredients, what are the different kind of flavors, what are the various kind of textures, etc, etc. This is the core knowledge you need to have before you start learning anything else. This is similar to learning OOP concepts. Then, you learn the techniques:- how do you saute, how do you fry, how do you cut, how do you clean. To me, this is analogous to learning design patterns. Once, you learn the techniques, not only do you learn the technique, but you also start building a common vocabulary that someone can instruct you in. This leads to you being able to follow concise recipes. SO, for example, if you know how to
dice a vegetable and you see a recipe that says "Dice an onion", you know what to do. You don't need anyone to explain to you at great length how to hold the knife and the vegetable, and where to cut. Similarily when you learn a design pattern (and UML which is the language that design patterns are expressed in ), you learn a completely new vocabulary. A architect/senior dev can come and tell you "Implement a factory there and a proxy here" and you are good to go. Sure, you can apply OOP without design patterns, just like you can cook without recipes. You just make it harder for yourself
Now, once you start using patterns... and this part takes years of experience.... you start seeing patterns behind the patterns. You become better and better at seeing how well patterns work at solving certain kind of problems. This is very similar to how cooks start building their own style. Once you have followed recipes for a long time, you start figuring out how different techniques blend together. Or you read other people's recipes and you can start imagining how they will work together, just because those techniques are so burned into your brain that you don't have to actually cook to know what something might taste like (although you might just do it for the fun of it). This is the point where you can start making design decisions. It take a lot of time, and it takes a lot of learning, and you never really stop learning this part, ALso, when you get to this point, you gain to learn a lot from watching other masters at their craft. You learn a lot by looking at the design of other applications, and evaluating how they make it work. You can spend a lifetime doing this and you will never get perfection. This is also why Chefs and Architects make the big bucks :p