Q:

Factory design pattern location of switch statements

I am trying to wrap my head around the usefulness of the factory design pattern.
Like many implementations of this design pattern (ie http://msdn.microsoft.com/en-us/library/ee817667.aspx) there is a switch statement in Main() that probes a string to decide which ConcreteComputerFactory to create (which is later sent to a ComputerAssembler.Assemble(ComputerFactory factory) method).
The way I see the problem: 
1. the user of the factory (Main()) "knows" the concrete factory implementations which by the very definition of the design pattern is supposed to be hidden from.
2. whenever a new concreteComputerFactory is introduced, the abstraction doesn't hold grounds! we have to go to the client (Main()) to add another if/case statement.
Proposition:
Move the if/switch statement/s to ComputerAssembler. (this has a slight problem that now ComputerAssembler has 2 reasons to change: a. overall stuff related to the creation b. adding a new ConcreteComputerFactory. but: this is certainly much better than in the client (Main))
I assume that I just don't fully grasp the idea yet. I would like to hear from you why the problems I specified are incorrect, and why my proposition isn't a better idea
Thanks :)

A:

The benefit of the factory design pattern does not come at factory creation time, but when the factory and its products are used.  The code that creates the factory knows what concrete type it is creating.  It's only after the factory has been created, when the factory and its products are used via their base interfaces instead of their concrete types, that you see the benefit of the factory pattern.  Code which operates on the base interfaces can create and use any number of different concrete classes without changing any code.
For example:
main()
{
  // The point isn't to hide concrete types at factory creation time
  Factory* fact = new ConcreteFactoryA();
  f(fact);
}

void f(Factory* fact)
{
  // This is where the benefit of the factory pattern is found, 
  // where the factory is *used*, not where it is created
  Product* p = fact.CreateProduct();
  p.DoSomething();
  UseProduct(p);
}

If I replace ConcreteFactoryA with ConcreteFactoryB, the code which creates the factory has to know about that change.  But I don't have to change f() in any way.  That's where the benefit comes in.  Once I've created the factory, the rest of my code can accommodate different concrete types without any changes.

