preface
In the last article, we talked about the simple factory model, taking the products provided by the store as an example. We explained to the store that the store will provide us with what products we want.
When using the simple factory pattern, the implemented store (factory class) is like this.
/** * Washing and care products store * * @author dashu * @since 2021/8/2 */ public class HygieneProductStore { public static HygieneProduct offer(HygieneProductEnum hygieneProduct) { if (HygieneProductEnum.SHAMPOO.equals(hygieneProduct)) { return new Shampoo(); } else if (HygieneProductEnum.BODY_WASH.equals(hygieneProduct)){ return new BodyWash(); } else { throw new UnsupportedOperationException("We don't sell this kind of products for the time being"); } } }
In the offer method of the store, we specify shampoo, the store creates shampoo for us, we specify shower gel, and the store creates shower gel object for us.
The simple factory pattern basically separates the production and use of objects.
But there is a flaw. At present, the store only provides shampoo and shower gel. If one day, the store is ready to supply more
What about sunscreen?
Then add a specific product category of sunscreen, and add an else in the offer method of the store to create a sunscreen object.
If you add [hand sanitizer], [conditioner] and other wash and care products later, of course, you can continue to create new product classes and add else to the offer method of the store, which can realize our functions.
However, if these products are frequently changed, added or deleted, you will find that if you use the simple factory model, you have to modify the factory class repeatedly. Every time we change, we have to modify the factory class once.
In this way, it is easy to modify a method of the same class frequently. Our example is still relatively simple, just new. What if the logic of factory production objects is complex.
There is an "opening and closing principle" in software design, which is open to expansion and closed to modification. This behavior of repeatedly modifying the offer method violates the opening and closing principle.
If the types of our products are basically unchanged or rarely changed, the simple factory model is enough, but if the types of products change frequently, we should introduce the factory method model - an upgraded version of the simple factory model.
1. Definitions
Factory method pattern is also called factory pattern, virtual constructor pattern or polymorphic factory pattern. In the factory method pattern, the factory parent class is responsible for defining the public interface for creating product objects, and the factory subclass is responsible for creating specific products, delaying the instantiation of the product class to the factory subclass.
2. Mode structure
form
- Abstract product
- Specific products
- Abstract factory
- Specific factory
The factory method pattern is compared with the simple factory pattern. The factory class has an abstract factory.
3. Code example
The factory method mode realizes that the washing and care product store sells washing and care products like this.
- There is an abstract product - washing and care products.
- There are some specific product categories - shampoo and shower gel.
- There is an abstract factory that defines an offer method. The implementation logic is that if you want shampoo, I will let the shampoo area provide you with a bottle of shampoo. If you want shower gel, I will let the shower gel area provide you with shower gel.
- Some specific factories inherit from abstract factories, such as shampoo area (specific factory) and shower gel area (specific factory).
If I want to add [sunscreen] products later, I will build a new [sunscreen] category (new specific products) and a new [sunscreen] zone (new specific factory).
If I want to remove [shampoo] products later, delete the [shampoo] category (existing specific products) and delete the [shampoo] zone (existing specific factories).
It looks like this, but whether you add or delete products, it will not affect the logic of abstracting the products produced by the factory.
When adding a product, you only need to pay attention to the new product. When deleting a product, you only need to pay attention to the deleted product without worrying about affecting other products.
------------------------------------------------------Code example----------------------------------------------------------
Abstract product
/** * Washing and care products * * @author dashu * @since 2021/8/20 */ public abstract class HygieneProduct { public abstract void whoAmI(); }
Specific products
/** * shampoo * * @author dashu * @since 2021/8/20 */ public class Shampoo extends HygieneProduct { public void whoAmI() { System.out.println("I'm shampoo"); } }
/** * Shower Gel * * @author dashu * @since 2021/8/20 */ public class BodyWash extends HygieneProduct { public void whoAmI() { System.out.println("I'm shower gel"); } }
Abstract factory
/** * Washing and care products store * * @author dashu * @since 2021/8/23 */ public abstract class HygieneProductStore { public abstract HygieneProduct offer(); }
Specific factory
/** * Shampoo zone * * @author dashu * @since 2021/8/23 */ public class ShampooArea extends HygieneProductStore { @Override public HygieneProduct offer() { return new Shampoo(); } }
/** * Shower Gel zone * * @author dashu * @since 2021/8/23 */ public class BodyWashArea extends HygieneProductStore { @Override public HygieneProduct offer() { return new BodyWash(); } }
client
/** * client * * @author dashu * @since 2021/8/23 */ public class Client { public static void main(String[] args) { ShampooArea shampooArea = new ShampooArea(); HygieneProduct shampoo = shampooArea.offer(); shampoo.whoAmI(); BodyWashArea bodyWashArea = new BodyWashArea(); HygieneProduct bodyWash = bodyWashArea.offer(); bodyWash.whoAmI(); } }
4. Advantages and disadvantages of the mode
advantage
- The factory method is used to create the products required by the client, and hides the instantiation details of specific product classes from the client. Users only need to care about the factory corresponding to the product, and do not need to care about the specific product class name and creation details.
- The factory can independently determine what products to create and how to create them. The details are completely encapsulated in the specific factory.
- When adding a new product, there is no need to modify the client, the abstract factory, or other specific factories and specific products. Just add a new specific factory and specific product.
shortcoming
- When a product needs to be added, a corresponding factory must be added. Each addition is added in pairs, which increases the complexity of the system to a certain extent.
- The introduction of abstraction layer increases the abstraction and understanding difficulty of the system.