Listen to this post
Create an interface for creating sets of dependent or related instances that implement a set of abstract types.
The Abstract Factory coordinates the instantiation of sets of objects that have varying implementations in such a way that only legitimate combinations of instances are ever created.
If an application is to be deployed on a variety of operating systems, it will need the “right one” of a number of different drivers such as Memory access, keyboard, mouse, file system, display, and sound. The right set of drivers for Windows will be different from the set of drivers for Linux, and yet different from those for OSX. Under no circumstances should a Windows display driver be used alongside a Linux memory manager. And so forth. Drivers “go together.” They are a family.
Qualities and principles
Each version of the factory is concerned with implementations for one case only. All client code couples solely to abstractions. Any otherwise-redundant implementation of the factories can be moved to the base class. Clients do not couple to concrete services, nor are they exposed to the number of cases there are, nor which one they are currently using, creating open-closedness. All factories are substitutable for each other.
Each concrete factory can be tested on its own, to ensure it builds the correct set of objects through a type check.
Questions and concerns
The pattern does not specify how the proper factory is selected, because there are many different ways to accomplish this (including another factory).
Supporting an entirely new kind of service will cause all factories and clients to be changed; if, in the example, we realized late in the day that we need a driver for touchscreens in each OS, this will cause sweeping maintenance across the system.
Note this is not a “failure” of the pattern. It reveals a lapse in the requirements analysis process that would have ultimately caused this problem anyway. Patterns lend clarity to such issues; they do not create them.