However, more often than not, from a requester's perspective, the product that he is looking for will be more polished than 'new Product()' that is to say the 'new Product()' would undergo some process before it is delivered.

We are using AbstractProduct instead of the actual Product, why?It's for the same reason that we prefer

List l = new ArrayList() toArrayList l = new ArrayList();

AbstractProduct is an abstraction of Product which is of interest to the factory andits users. It makes sure the same factory can work when new Products are introduced as long as they are instances of the same abstraction. It also means the factory returns abstractions not actual implementations so users of this factory are also lightly coupled.Once we have an implementation like above, it can be used as

ProductFactory pf = new ProductFactory();pf.getProduct();

Observe that the factory is tightly coupled with actual implementations of Products.Now consider introducing a new factory, so that a client (requester) has the option to choose one of these factories where he wants the product from. That choice should be construed as the Context in which the product is created/requested.e.g. a Spreadsheet instance from MSOffice or one from OpenOffice. Client would makje a decision to go for one of these. The choice is basically boils down to selecting one of MSOfficeSpreadsheetFactory or OOfficeSpreadsheetFactory.However, before the spreadsheet is returned, it should be assigned a default name and should also be saved in a temporary location (this post-process is henceforth referred as polishing). This has to happen irrespective of whether it is MSO or OO spreadsheet.At this stage we will have these two factories:

So far so good. Lets take a moment and analyze where things could get complicated with this approach.What happens when a new Factory is introduced and/or and new polishing procedure is introduced. This would require a change in the SpreadsheetFactory and all its concrete implementations as implementations are using superclass methods. We can work this out by moving the polishing out of implementations and thus leaving them responsible for creation alone.Instead of invoking createSpreadsheet() which is implemented in the subclassintroduce another method getSpreadsheet() in SpreadsheetFactory. This moves back the creation control to the SpreadsheetFactory, the superclass.

What we gain from this approach:The factory SpreadsheetFactory is not dependent on actual implementations of Spreadsheets. Still, the factory knows how to create and return implementations of Spreadsheets. How does that happen...The factory is delegating the actual instantiation to its subclass. The subclass is selected by the requester (which is basically the Context selection). The SpreadsheetFactory class would not be impacted by addition of new implementations.It's important to note that the essence of this pattern lies in how the factory should be designed so that the factory itself is not coupled with what it creates and hence can be used to create products depending on the context that it operates in. See it from the point of view of the getSpreadsheet() method, not from the point of view of the client.This pattern is usually applied to scenarios where factories return a certain type of product.