I. Introduction of models
The factory method mode considers the production of a kind of products, such as TV factory only produces TV, pizza shop only produces pizza, etc.
Similar products are called the same grade, that is to say: the factory method mode only considers the production of products of the same grade, but in real life, many factories are comprehensive factories that can produce products of multiple grades (types). For example, both animals and plants are raised on the farm, and KFC produces hamburgers and fried chicken.
Abstract factory pattern is an upgraded version of factory method pattern. Factory method pattern only produces one level of products, while abstract factory pattern can produce multiple levels of products. A group of products at different levels produced by the same specific factory is called a product family, as shown in the following figure: the corresponding relationship between televisions and air conditioners generated by Haier factory and TCL factory.
1.1 definition
The abstract factory pattern provides an interface for creating families of related or interdependent objects without specifying the specific class of the product to be produced.
The following conditions are generally met when using abstract factory mode:
- There are multiple product families in the system. Each specific factory creates products of the same family but belonging to different hierarchical structures
- The system can only consume the products of one family at a time, that is, the products of the same family can be used together.
1.2 advantages
- It has the advantages of factory mode
- The multi-level products associated in the product family can be managed together within the class, instead of introducing multiple new classes for management
- When a product family is needed, the abstract factory can ensure that the client always uses the product family of the same product
- Abstract factory enhances the scalability of the program. When adding a new product family, there is no need to modify the source code and meet the opening and closing principle
1.3 disadvantages
- When a new product needs to be added to the product family, all factory classes need to be modified
- It increases the abstraction and understanding difficulty of the system
2, Structure and Implementation
2.1 structure
Abstract factory mode, like factory method mode, is also composed of four elements: abstract factory, concrete factory, abstract product and concrete product. However, the number of methods in abstract factory is different, so is the number of abstract products.
- Abstract factory: it provides an interface for creating products. It contains multiple methods for creating products newProduct(), which can create multiple products of different levels.
- Concrete factory: it mainly realizes the abstract methods in the abstract factory and completes the creation of specific products.
- Abstract Product: it defines the specification of the Product and describes the main characteristics and functions of the Product. The abstract factory has multiple Abstract products.
- Concrete product: it implements the interface defined by the abstract product role and is created by the specific factory. It corresponds to the specific factory one by one.
2.2 realization
2.2.1 class diagram
2.2.2,NYPizzaStore
package com.erlang.factory.abstract_; /** * @description: New York Pizza * @author: erlang * @since: 2022-02-08 22:28 */ public class NYPizzaStore extends PizzaStore { @Override protected Pizza createPizza(String type) { Pizza pizza = null; PizzaIngredientFactory factory = new NYPizzaIngredientFactory(); if (type.equals("cheese")) { pizza = new CheesePizza(factory); pizza.setName("NY Style Cheese Pizza"); } else if (type.equals("clam")) { pizza = new ClamPizza(factory); pizza.setName("NY Style Clam Pizza"); } return pizza; } }
2.2.3,PizzaIngredientFactory
package com.erlang.factory.abstract_; /** * @description: Chicago pizza ingredients processing factory * @author: erlang * @since: 2022-02-09 22:38 */ public interface PizzaIngredientFactory { /** * dough * * @return dough */ Dough createDough(); /** * sauce * @return */ Sauce createSauce(); }
2.2.4,NYPizzaIngredientFactory
package com.erlang.factory.abstract_; /** * @description: New York Pizza * @author: erlang * @since: 2022-02-09 22:59 */ public class NYPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThinCrustDough("Thin Crust Dough"); } @Override public Sauce createSauce() { return new MarinaraSauce("Marinara Sauce"); } }
2.2.5,ChicagoPizzaIngredientFactory
package com.erlang.factory.abstract_; /** * @description: Chicago pizza * @author: erlang * @since: 2022-02-09 22:39 */ public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { @Override public Dough createDough() { return new ThickCrustDough("Extra Thick Crust Dough"); } @Override public Sauce createSauce() { return new PlumTomatoSauce("Plum Tomato Sauce"); } }
2.2.6,Dough
package com.erlang.factory.abstract_; /** * @description: Dough interface * @author: yj * @since: 2022-02-09 22:42 */ public interface Dough { /** * dough * * @return Return to dough */ String getDough(); }
2.2.7,ThickCrustDough
package com.erlang.factory.abstract_; /** * @description: * @author: erlang * @since: 2022-02-09 22:53 */ public class ThickCrustDough implements Dough { private String dough; public ThickCrustDough(String dough) { this.dough = dough; } @Override public String getDough() { return dough; } }
2.2.8,ThinCrustDough
package com.erlang.factory.abstract_; /** * @description: * @author: erlang * @since: 2022-02-09 22:57 */ public class ThinCrustDough implements Dough { private String dough; public ThinCrustDough(String dough) { this.dough = dough; } @Override public String getDough() { return dough; } }
2.2.9,Sauce
package com.erlang.factory.abstract_; /** * @description: * @author: erlang * @since: 2022-02-09 22:44 */ public interface Sauce { /** * sauce * * @return sauce */ String getSauce(); }
2.2.10,PlumTomatoSauce
package com.erlang.factory.abstract_; /** * @description: * @author: erlang * @since: 2022-02-09 22:55 */ public class PlumTomatoSauce implements Sauce { private String sauce; public PlumTomatoSauce(String sauce) { this.sauce = sauce; } @Override public String getSauce() { return sauce; } }
2.2.11,MarinaraSauce
package com.erlang.factory.abstract_; /** * @description: * @author: erlang * @since: 2022-02-09 22:57 */ public class MarinaraSauce implements Sauce { private String sauce; public MarinaraSauce(String sauce) { this.sauce = sauce; } @Override public String getSauce() { return sauce; } }
2.2.12,CheesePizza
package com.erlang.factory.abstract_; /** * @description: Cheese pizza * @author: erlang * @since: 2022-02-08 21:23 */ public class CheesePizza extends Pizza { PizzaIngredientFactory ingredientFactory; public CheesePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } @Override public void prepare() { System.out.printf("Preparing %s Pizza\n", name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); } }