Summary on basis of the book ,,Design Patterns: Elements of Reusable Object-Oriented Software'', by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Addison-Wesley, 1995.class CertainFactory extends Factory{
@Override
ProductA createProductA(){
return new CertainProductA();
}
}
We do have an abstract Factory which defines an interface for instantiating object of general types. In implementing subclasses we instantiate objects as cetrain subtypes of the general types.
We can use such pattern for example for a toolkit that supports multiple look-and-feel standards. Each standard will then have corresponding Factory subclass, and for each widget type a set of specific classes. Clients have no knowledge even of the concrete widgets, just of the abstract Factory and general widget types.
We use it when we want to configure system with one of multiple
families of product, and when we want to
impose a constraint that objects specific for particular family should be used
together; when we want to separate the
system from its product
creation, composition and representation; when we want to
hide the implementation of products, i.e. when providing a
class library;
Consequences and variations- the concrete Factory is usually created at run-time
- (-) extending to use new kinds of product is difficult
- (+) it promotes consistency among the product families
- concrete factories are usually singletons
- creating concrete product in concrete factories can be done either with FactoryMethod pattern (the disadvantage is we need a new concrete factory with overriden factory methods for each family), or with Prototype pattern (in this case we instantiate the factories with a set of prototypes of each product type - in this way we can reduce the number of required concrete factories)
- instead of specifying a separate method for creating each product type we can have just one parametrized method - but this approach is less safe: all products have to have same subclass in case of statically types languages, and the client will not know anything about the specific object type - which causes a classic trade-off for a highly flexible and extensible interface;