In this episode, we look at the Abstract Factory pattern. This is a creational pattern which means it has to do with creating and utilizing class instances. There is also a Factory pattern that will be covered later in the series.
The Abstract Factory Defined
It helps to start with the “Gang of Four” definition and then we will dig into that.
Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
This may seem a bit abstract. However, it is a crucial cog in creating an object-oriented application or system. As always, the real world provides us with some good examples of how this would be used. Think of an automobile factory. Within a complex, there are multiple assembly lines or configurations to create various models of cars. Each configuration would be a “factory” that produces an instance of a specific class of car. An abstract factory would be a way to utilize the similarities across those lines. Similarities may include references to workers, process steps, or other such items. You can refer to the quality assurance process without having to specify it for a specific model.
Applying The Pattern
You may wonder where an Abstract Factory is useful. As it happens, this is a pattern that is nearly as useful as a class definition. When you use a factory pattern, you expand the flexibility of your application. There are some excellent examples, but we will stick with one for now. This may even be common usage in your experience.
For our example, we will have an address book application that can use a text file, a MySQL database, or an API to save data. The backend that we use does not change the standard features we need. A short list of these features is going to look familiar.
- Load Data for a record
- Save Data
- Load a list of data based on criteria
- Create a record
- Delete a record
The good news (and power of the pattern) is that we can build a standard interface with these features and plugin the backend system we need. We just need each of them to adopt the same interface, and then we can “ask” for the one we want at runtime. This can be a requirement based on user preferences or something like this might be a solution to an application that is connected some of the time.
Java, PHP, C#, etc.
The good news about this pattern is that the coding is very similar no matter the language you use. The Abstract Factory itself provides functionality and is an interface. In our example, we can call it the DataStore interface. This will have each of the methods listed above defined, and then we will have a concrete implementation that uses the interface for every data store type we want.
When we need to add support for a new data store type, it is just another class we can plug in. The usage will be to expect the interface (DataStore), and then we pass in the appropriate instance. That makes this a pattern that we can efficiently use to solve a wide range of OOP problems. Keep it in mind the next time you need to support multiple approaches as part of your solution.