We often say that the factory pattern is not a specific design pattern. In “GoF design Patterns (23 classic design patterns)”, the specific “Factory Pattern” refers to Factory Method Pattern and Abstract Factory Pattern. However, we often refer to Simple Factory Pattern, Factory method Pattern, and abstract Factory Pattern as Factory Pattern.

Simple Factory Pattern

Simple factories are also called static factories. The simple factory pattern is not a design pattern, or it is not in the Gof inductive design pattern. It’s one of our design approaches. When we create an object, we usually create it in a new way, which is implementation oriented programming (when we have identified the object, the related functionality has been identified).

Benefits of using the simple factory pattern to create objects:

  • Easy to get objects

  • You can separate the details of object creation from the business code, encapsulating and hiding the details of object creation

  • The way the object is created has changed, so only the methods in the factory need to be modified, not at each caller.

The simple factory method is very simple to implement:

Public interface IProduct {void display(); }Copy the code
// Implements A public class AProduct implements IProduct {@override public void display() {system.out.println (" implements IProduct "); }}Copy the code
// product B public class implements IProduct {@override public void display() {system.out.println (" implements IProduct "); }}Copy the code
Public static IProduct createProduct(String type) {if ("A".equals(type)) {return new AProduct(); } if ("B".equals(type)) { return new BProduct(); } return null; } public static void main (String [] args) {/ / A product IProduct aProduct. = SimpleFactory createProduct (" A "); aProduct.display(); . / / B product IProduct bProduct = SimpleFactory createProduct (" B "); bProduct.display(); }} output: I am product A and I am product BCopy the code

The simple factory is simple to implement, but it also has some drawbacks. The main one is that it violates the open and closed principle (open for extension, closed for modification). When we need to add new products, we need to modify the static methods in the simple factory.

Factory Method Pattern

Factory Method Pattern: Defines an interface for creating objects and lets subclasses decide which classes to instantiate. The factory method pattern delays instantiation of a class to its subclasses.

The factory method pattern contains four roles: abstract product, concrete product, abstract factory, and concrete factory

Concrete products (concrete objects), created by concrete factory methods.

This is illustrated in code

Public interface IProduct {void display(); }Copy the code
Public class AProduct implements IProduct {@override public void display() {system.out.println (" I'm A product "); }}Copy the code
Public class implements IProduct {@override public void display() {system.out.println (" implements IProduct "); }}Copy the code
Public interface IProductFactory {IProduct createProduct(); }Copy the code
A public class implements IProductFactory {@override public IProduct createProduct() {return new AProduct(); }}Copy the code
Public class implements IProductFactory {@override public product implements IProductFactory () {return new BProduct(); }}Copy the code
Public class Client {public static void main(String[] args) {IProductFactory aProductFactory = new ProductAFactory(); / / create A product IProduct aProduct. = aProductFactory createProduct (); aProduct.display(); IProductFactory bProductFactory = new ProductBFactory(); . / / B product creation IProduct bProduct = bProductFactory createProduct (); bProduct.display(); }} output: I am product A and I am product BCopy the code

If we need to add “product C”, we just need to add an implementation class for “product C” and a specific factory for “product C”.

The factory method pattern is relatively simple compared to the factory method, which is mainly implemented to close for change (to change, you only need to add a new subclass).

“Deferring instantiation of a class to its subclasses” in the factory method pattern is an important way to increase system extensibility.

From the demo code, of course, when you add new products, you need to write a new specific products, but also to provide with the corresponding concrete factory class, number of system classes will increase in pairs, to a certain extent, increased the complexity of the system, there are more classes need to compile and run, will bring some extra overhead system.

Abstract Factory Pattern

The abstract factory pattern provides an interface for creating a series of related or interdependent objects.

The abstract factory pattern is similar to the factory approach in that it uses concrete factories to create concrete products. But instead of creating a class of products (all concrete products are implementations (inherits) of the same abstract product and are therefore grouped into a class of products), an abstract factory creates a series of related or interdependent products. What is a set of or interdependent products? Take a real example, refrigerator is a kind of products, the actual haier refrigerator, refrigerator and so on. And a series of products are different products under the same brand, such as Haier series: Haier refrigerator, Haier air conditioning, Haier washing machine; Midea series: Midea refrigerator, midea air conditioner, Midea washing machine. Often, a group of products is also called a family of products

To demonstrate the abstract factory in code:

Public interface ICard {void display(); }Copy the code
Public interface IProduct {void display(); }Copy the code
Public class implements IProduct {@override public void display() {system.out.println (" implements IProduct "); }}Copy the code
Public class ACard implements ICard {@override public void display() {system.out.println (" implements ICard "); }}Copy the code
Public class implements IProduct {@override public void display() {system.out.println (" implements IProduct "); }}Copy the code
Public class implements ICard {@override public void display() {system.out.println (" implements ICard "); }}Copy the code
Public interface AbstractFactory {/** * createProduct * @return */ IProduct createProduct(); /** * create a card coupon * @return */ ICard createCard(); }Copy the code
Public class implements AbstractFactory {@override public IProduct createProduct() {return new AProduct(); } @Override public ICard createCard() { return new ACard(); }}Copy the code
Public class implements AbstractFactory {@override public IProduct createProduct() {return new BProduct(); } @Override public ICard createCard() { return new BCard(); }}Copy the code
Public static void main(String[] args) {public static void main(String[] args) {// A system product AbstractFactory aFactory = new AFactory(); IProduct aProduct = aFactory.createProduct(); ICard aCard = aFactory.createCard(); aProduct.display(); aCard.display(); // AbstractFactory bFactory = new bFactory (); IProduct bProduct = bFactory.createProduct(); ICard bCard = bFactory.createCard(); bProduct.display(); bCard.display(); }} output: I am A product, I am A card coupon, I am B product, I am B card couponCopy the code

An abstract factory can create a series of products, but it has the disadvantage that adding a new product to the product family requires all concrete factories to re-implement a method for creating the new product.