As your question is covering a lot of ground, with a lot of assumptions, I'll single out the subject of your question:
Why do we need so many classes in design patterns
We do not. There is no generally accepted rule that says that there must be many classes in design patterns.
There are two key guides for deciding where to put code, and how to cut your tasks into different units of code:
- Cohesion: any unit of code (be it a package, a file, a class or a method) should belong together. I.e., any specific method should have one task, and do that one well. Any class should be responsible for one larger topic (whatever that may be). We want high cohesion.
- Coupling: any two units of code should depend as little on each other as possible - there should especially be no circular dependencies. We want low coupling.
Why should those two be important?
- Cohesion: a method that does a lot of things (e.g., an old-fashioned CGI script that does GUI, logic, DB access etc. all in one long mess of code) becomes unwieldy. At the time of writing, it is tempting to just put your train of thought into a long method. This works, it is easy to present and such, and you can be done with it. Trouble arises later: after a few months, you may forget what you did. A line of code at the top might be a few screens away from a line on the bottom; it is easy to forget all details. Any change anywhere in the method may break any amount of behaviours of the complex thing. It will be quite cumbersone to refactor or re-use parts of the method. And so on.
- Coupling: anytime you change a unit of code, you potentially break all other units that depend on it. In strict languages like Java, you might get hints during compile time (i.e., about parameters, declared exceptions and so on). But many changes are not triggering such (i.e. behavioural changes), and other, more dynamic, languages, have no such possibilities. The higher the coupling, the tougher it gets to change anything, and you might grind to a halt, where a complete re-write is necessary to achieve some goal.
These two aspects are the base "drivers" for any choice of "where to put what" in any programming language, and any paradigm (not only OO). Not everybody is explictly aware of them, and it takes time, often years, to get a really ingrained, automatic feeling on how these influence software.
Obviously, those two concepts do not tell you anything about what to actually do. Some people err on the side of too much, others on the side of too little. Some languages (looking at you here, Java) tend to favour many classes because of the extremely static and pedantic nature of the language itself (this is not a value statement, but it is what it is). This becomes especially noticeable when you compare it to dynamic and more expressive languages, for example Ruby.
Another aspect is that some people subscribe to the agile approach of only writing code that is necessary right now, and to refactor heavily later, when necessary. In this style of development, you would not create an
interface when you only have one implementing class. You would simply implement the concrete class. If, later, you need a second class, you would refactor.
Some people simply do not work that way. They create interfaces (or, more generally, abstract base classes) for anything that ever could be used more generally; this leads to a class explosion quickly.
Again, there are arguments for and against, and it does not matter which I, or you, prefer. You will, in your life as software developer, encounter all extremes, from long spaghetti methods, through enlightened, just-big-enough class designs, up to incredibly blown-up class schemes that are much overengineered. As you get more experienced, you will grow more into "architectural" roles, and can start to influence this in the direction you wish to. You will find out a golden middle for yourself, and you will still find that many people will disagree with you, whatever you do.
Hence, keeping an open mind is the most important bit, here, and that would be my primary advice to you, seeing that you seem to be much in pain about the issue, judging by the rest of your question...