Card 06/ 08
Adding a Product Kind Means Editing Every Factory
A new product kind is one new method on the interface and one more in every family's factory.
Abstract Factory makes adding a new family cheap and adding a new kind of product expensive, and teams that pick it for flexibility are often surprised by the second half. A new kind of product is a new method on the abstract factory, which every concrete factory must then implement. This card counts the cost of each change, so you can tell in advance which one your design will face.
Take the cloud kit with storage and queues for three providers: AWS, Google Cloud and Azure. Two changes are on the table: add a fourth provider, or add a cache to the kit.
| Change | New classes | Existing classes edited |
|---|---|---|
| A fourth provider | 3: one factory and one storage and one queue for it | 0 |
| A cache, a third kind | 4: a Cache interface and one cache for each provider | 4: CloudFactory and all three provider factories gain create_cache |
A new family is pure addition: nothing that works today is opened. A new kind of product edits the abstract factory and every concrete factory, and the number grows with each family you have. With ten providers, a cache means eleven edited classes.
That asymmetry comes with the pattern itself, however it is implemented. The Gang of Four say it directly: supporting new kinds of products is difficult. So the useful question before choosing the pattern is which of the two changes your system will face more often. A cloud kit gains providers rarely and services often; a widget kit gains themes often and widget kinds rarely.
When new kinds come often, two softer forms exist. A factory can have one generic method, such as create(kind), which needs no new method per kind but gives up the type checker's help. Or each kind can get its own Factory Method, and the family guarantee is enforced by configuration rather than by structure.
← → move through sections and cards