Creational Design Patterns: Abstract Factory Pattern
The Abstract Factory Pattern is a creational pattern and is one of the most popular patterns along with the builder and the factory pattern. Creational patterns are used in order to create objects instead of creating objects directly using a constructor.
The Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.
The intent in employing the pattern is to insulate the creation of objects from their usage and to create families of related objects without having to depend on their concrete classes.
By using that pattern the client doesn’t have to be aware of the objects and their implementation details. It is a responsibility of the Abstract Factory’s Implementation to implement the objects and handle all the details in order to do that successfully.
So let’s get into action and start solving problems.
Supposing we are responsible for the canning process of various products.
Regarding the canning procedure there are two objects that have to be created. The can’s main body and the can’s top.
Also considering the fact that we might have various forms of canning we might as well have various factories which can handle the canning process. For example we might have a factory for beer canning or a factory for food canning.
Regarding the description above it seems that abstract factory is the way to go. We do have a family of objects and we do want to hide the construction of these objects.
We will start by adding two interfaces regarding the functionality of a can’s top and a can’s body.
package com.gkatzioura.design.creational.abstractfactory; public interface CanTop { void open(); }
package com.gkatzioura.design.creational.abstractfactory; public interface CanBody { void fill(); }
Then we shall create an abstract factory which will provide the methods to implement in order to create those objects.
package com.gkatzioura.design.creational.abstractfactory; public abstract class CanningFactory { public abstract CanTop createTop(); public abstract CanBody createBody(); }
As mentioned we have cases of beer canning. Thus we will have implementations of the CanTop and the CanBody class.
package com.gkatzioura.design.creational.abstractfactory.beer; import com.gkatzioura.design.creational.abstractfactory.CanTop; public class BeerCanTop implements CanTop { public void open() { } }
package com.gkatzioura.design.creational.abstractfactory.beer; import com.gkatzioura.design.creational.abstractfactory.CanBody; public class BeerCanBody implements CanBody { public void fill() { } }
Then we shall implement a Beer Canning Factory.
package com.gkatzioura.design.creational.abstractfactory.beer; import com.gkatzioura.design.creational.abstractfactory.CanBody; import com.gkatzioura.design.creational.abstractfactory.CanTop; import com.gkatzioura.design.creational.abstractfactory.CanningFactory; public class BeerCanningFactory extends CanningFactory { public CanTop createTop() { return new BeerCanTop(); } public CanBody createBody() { return new BeerCanBody(); } }
The other case is food canning. We will provide implementations of the CanTop and CanBody class for this case too.
package com.gkatzioura.design.creational.abstractfactory.food; import com.gkatzioura.design.creational.abstractfactory.CanBody; public class FoodCanBody implements CanBody { public void fill() { } }
package com.gkatzioura.design.creational.abstractfactory.food; import com.gkatzioura.design.creational.abstractfactory.CanTop; public class FoodCanTop implements CanTop { public void open() { } }
As a last step we will provide the abstract factory implementation for cases of food canning.
package com.gkatzioura.design.creational.abstractfactory.food; import com.gkatzioura.design.creational.abstractfactory.CanBody; import com.gkatzioura.design.creational.abstractfactory.CanTop; import com.gkatzioura.design.creational.abstractfactory.CanningFactory; public class FoodCanningFactory extends CanningFactory { public CanTop createTop() { return new FoodCanTop(); } public CanBody createBody() { return new FoodCanBody(); } }
What we just did is using the abstract factory pattern in order to create a family of objects regarding the canning process. We insulated the creation process from the usage of the CanTop and CanBody. Also we are able to create a family of objects without depending on their concrete classes.
You can find the sourcecode on github.
On the next blog post we will have a look at the Factory Pattern.
Also I have compiled a cheat sheet containing a summary of the Creational Design Patterns.
Sign up in the link to receive it.
Published on Java Code Geeks with permission by Emmanouil Gkatziouras, partner at our JCG program. See the original article here: Creational Design Patterns: Abstract Factory Pattern Opinions expressed by Java Code Geeks contributors are their own. |