“Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”
Design Patterns – Elements of Reusable Object-Oriented Software
So let’s begin revising the “traditional” object-oriented design patterns. I’m going to stick closely to the book, so the order of posts will be the same as the order in the book.
Abstract Factory is a creational pattern. It means that its sole purpose of such a class is to create another objects/classes. An Abstract Factory pattern has the following participants:
- Abstract base factory class/interface
- Concrete factory subclasses derived from the base class, implements the interface
- Abstract product: the abstract base class of the products to be created
- Concrete product: the concrete implementation of the abstract product.
- Client: uses the abstract factory and the abstract product classes, without further knowledge of their concrete implementations.
A live example in the .NET Framework is the DbProviderFactory class of the System.Data.Common namespace. It uses a string (the name of the concrete factory class) to return concrete factories for different data providers. Then you can use the factory instance to instantiate abstract product classes, such as DbConnection and DbCommand. Note that you have no knowledge of the underlying concrete type (for example, SqlConnection), the Abstract Factory pattern takes care of it for you.
DbProviderFactory factory = DbProviderFactories.GetFactory(“System.Data.SqlClient”);
DbConnection connection = factory.CreateConnection(“my connection string”);
Behind the scenes, our factory uses SqlClientFactory, which instantiates a SqlConnection object for us. It is possible, because we defined a common set of methods for each concrete factory (such as CreateConnection), and these methods creates and returns common abstract products, with a similar set of common functionality (such as the ConnectionString property). Of course, the concrete derived factory classes overrides the methods to create the concrete products your application needs.
And what’s it good for? In the case of DbProviderFactory, applying this pattern helps you build an application with a provider-agnostic data access layer, so you can feed it from any data source (as long as there’s a valid provider for it). There’s a catch however, it’s difficult to support new kinds of products, because to do so, you’ll need to introduce changes to the abstract factory class, and it results in presenting the same changes in all concrete derivates of it. But there’s a pattern for that, too!
Design Patterns (book) pp 87 – 95