From the course: Spring 6: Design Patterns

The factory pattern

- [Instructor] Now, we will discuss possibly the most well-known pattern that exists throughout all of design patterns. And that is the factory pattern. Let's start by talking about where it is used within the spring framework. We just alluded to the fact that the BeanFactory, the core of the IOC container is ultimately a factory. It serves concrete classes constructed at startup to other objects created at startup or during runtime as part of the inversion control process. The factory being interface is a generic or templated interface that is used to encapsulate object construction logic when that logic has special considerations or is non-static. Otherwise, you could just use a factory method, a little bit more on that later. But there's a couple different ways that factory manifests itself within spring. The factory pattern and its adjacent factory being interface are leveraged heavily by the framework, as I alluded to, just the IOC container itself leverages it. So, let's talk about the actual pattern. Now, we're not going to go so deep into the pattern that you fully understand it, but I do want to talk at a nutshell level what the pattern entails. A factory allows construction of similar classes of different types using a factory method. The method call creates the object for you and ultimately serves it back to you when you call this factory method. Constructed objects are from classes that share an interface or parent class. So, we have the pets, we've got dogs and cats, they share a common pet interface, and the factory can serve either canine or feline to us because they have that common lineage. So, what are the problems that we're trying to solve with the factory method? First of all, it allows you to not worry about class construction in more than one place. If I have to create a dog and create a cat, and then create another dog, I've got to think about that logic, and it may get scattered throughout my code, which tends to increase the risk of errors. By using a factory, we can encapsulate that construction and simply say, "Give me a dog, give me a cat," and it will do that knowing that it shares a pet. And as a matter of fact, as we're going to talk about here in a bit, we actually can reference all of that abstractly. It also allows you to leverage the interface for repetitive operations. Again, back to our dog and cat scenario. When we code this, we may actually code to the PET interface and allow the factory to just serve the appropriate concrete implementation. A week later, we may decide that we want birds in our factory, and by doing this, we don't have to change because we've coded to the interface, we only encapsulate the factory method to service a bird. Now, this lack of object construction not only cleans up the code, but as I alluded to, it makes copy and paste errors less likely, because I don't have this construction littered throughout my code base, instead it's encapsulated in one spot. Outside of spring, there is a distinct strategy that we often use to create factories. The first, and this is very important, you will always do better if you code to an interface, otherwise, what's really the purpose of the factory other than encapsulation, you're kind of missing a lot of the value if you're coding to concrete implementations. You create that common interface. You then create one or more classes that gives instances of the interface, and I say one or more because there is an abstract pattern with this. The implementation of the concrete classes from the interface will then allow us to serve them out of the factory. So, we still need the concrete classes and they simply implement the interface. Now, I alluded to this abstract factory pattern, and this is really a level of advancement that we see on the factory pattern as a whole. This kind of takes that pattern one step further and makes your code even more abstracted in a way that you're dealing with interfaces. It really becomes a factory of factories! It adds this level of abstraction that becomes powerful if you have a bunch of types that also themselves have a bunch of types, because now I can say, "Give me a pet," and it will know, not only do I want a canine, but I want a Labrador as we traverse that inheritance layer. Now, that's all we're going to talk about with the factory pattern, but let's jump into how we would do this in spring outside of the raw Java use case.

Contents