1.1 Simple Factory Pattern
Simple Factory Pattern is the creation of classes, also called Static Factory Method pattern. The simple factory pattern uses a factory object to decide which instance of the product class to create.
1.1.1 Several forms of factory pattern
The factory pattern is specifically responsible for instantiating a large number of classes with common interfaces. The factory pattern can dynamically decide which class to instantiate. The factory pattern has the following forms:
Simple Factory (Simple Factory) pattern: also known as the Static Factory Method (Static Factory Method) pattern.
Factory Method pattern: also known as Polymorphic Factory pattern or Virtual Constructor pattern.
Abstract Factory pattern: also called toolbox (Kit or Toolkit) pattern.
The picture below shows a simplified class diagram of the simple factory pattern.
The simple factory pattern, or static factory method pattern, is a special implementation of different factory method patterns. In Java language, the usual factory method pattern cannot give the static factory method pattern by degenerating the design functionality.
1.1.2 Introduction of simple factory mode (general mode)
For example, there is a farm that produces various fruits, including apples, strawberries, and grapes; the farm’s gardener (FruitGardener) needs Provide corresponding fruits according to customer needs. Let’s take a look at how to implement this process using the simple factory pattern, as shown below:
The implementation source code of this pattern is as follows:
1.1.2.1 Product interface - Fruit interface: Fruit.java
package com.lavasoft .patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:Fruit.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:26:51
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode Mode – Simple Factory Mode – General Mode
* ReadMe: Abstract Product Role: Factory’s Fruit Product Interface – Fruit
*/
public interface Fruit {
/**
*Planting
*/
void plant();
/**
*Growth
*/
void grow ();
/**
* Harvest
*/
void harvest();
}
1.1.2.2 Product - Pingguo category: Apple.java
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:Apple.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:47:25
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode Mode – Simple Factory Mode – General Mode
* ReadMe: Fruit Factory Products: Apple
*/
public class Apple implements Fruit {
private int treeAge;
/**
*Planting
*/
public void plant() {
System.out.println("Apple has been planted .");
}
/**
*Growth
*/
public void grow() {
System.out.println("Apple is growing...");
}
/**
* Harvest
}
/**
* @return Returns the age of the tree
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
}
1.1.2.3 产品-草莓类:Strawberry.java
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:Strawberry.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:45:09
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode Mode – Simple Factory Mode – General Mode
* ReadMe: Fruit Factory Products: Strawberry
*/
public class Strawberry implements Fruit {
/**
*Growth
*/
public void grow() {
System.out.println("Strawberry is growing...");
}
/**
* Harvest
*/
public void harvest() {
System.out.println("Strawberry has been harvested.");
}
/**
*Planting
*/
public void plant() {
System.out.println("Strawberry has been planted.");
}
/**
* Helper method
*/
public static void log(String msg) {
System.out.println(msg);
}
}
1.1.2.4 产品-葡萄类:Grape.java
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:Grape.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 0:36:56
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode Mode – Simple Factory Mode – General Mode
* ReadMe: Fruit Factory Products: Grapes
*/
public class Grape implements Fruit {
private boolean seedless; //是否有籽
/**
*Planting
*/
public void plant() {
System.out.println("Grape has been planted.");
}
/**
*Growth
*/
public void grow() {
System.out.println("Grape is growing...");
}
/**
* Harvest
*/
public void harvest() {
System.out.println("Grape has been harvested.");
}
/**
* @return Whether there are seeds
*/
public boolean getSeedless() {
return seedless;
}
/**
* There is a seed-free assignment method
*/
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
/**
* Helper method
*/
public static void log(String msg) {
System.out.println(msg);
}
}
1.1.2.5 工厂-园丁类:FruitGardener.java
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:FruitGardener.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 1:03:27
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode Mode--Simple Factory Mode--General Mode
* ReadMe: Factory Role: Fruit Gardener, Produces Fruit Products
*/
public class FruitGardener {
/**
* Static factory method
* @param which: specific product name
* @return a fruit object
* @throws BadFruitException
*/
public static Fruit factory(String which) throws BadFruitException {
if (which.equalsIgnoreCase("apple")) {
new Apple();
{ } else {
to be thrown, - to .ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:BadFruitException.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 1:04:56
* Factory Mode - Simple Factory Mode - General Mode
* ReadMe: Factory Exception Handling Class*/
public class BadFruitException extends Exception {
super(msg); //Call the constructor of the parent class
}
}
1.1.2.7 General factory Pattern test class
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 1:12:08
* Factory Mode Mode – Simple Factory Mode – General Mode
* ReadMe: Test Classes for General Factory Mode*/
public class TestApp {
* Test method
*/
private void test(String fruitName) {
Try {u u FRUIT F = FRUITGARDENER.FACTORY (FRUITNAME);
System.out.println ("Congratulations! Production of a fruit object:" + fruitName); System.out.println (" Sorry! The factory is currently unable to produce the product you requested: " + fruitName);
}
/**
* Application entry method
*/
public static void main(String args[]) {
TestApp t = new TestApp();
t.test("apple");
t.test("grape ");
t.test("strawberry");
t.test("car"); //An exception will be thrown here. Can the fruit factory produce cars? Hahahaha...
}
}
1.1.2.8 Test run results
Congratulations! A fruit object is produced: apple
Congratulations! A fruit object is produced: grape
Congratulations! A fruit object is produced: strawberry
Sorry! The factory is currently unable to produce the product you want: car
Bad fruit request
com.lavasoft.patterns.simplefactory.ybgc.BadFruitException: Bad fruit request
at com.lavasoft.patterns.simplefactory.ybgc.FruitGardener.factory(FruitGardener.java:28)
at com.lavasoft.patterns. simplefactory.ybgc.TestApp.test(TestApp.java:19)
at com.lavasoft.patterns.simplefactory.ybgc.TestApp.main(TestApp.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Process finished with exit code 0
From the results, it seems that there is an exception because a type car that cannot be produced by the factory is entered. (car), hahahaha, can an orchard produce cars? Let the kindergarten children tell you!
1.1.3 The general structure of the simple factory pattern
To summarize, from the implementation of the simple factory pattern above, we can see that the simple factory pattern needs to be implemented
Factory role: gardener
Abstract product: Fruit interface
Specific products: apples, grapes, strawberries
In addition, it is generally necessary to implement
Factory exception class
Customer class
The general structure diagram of the simple factory pattern is as follows:
1.1.4 Simple factory pattern Implementation
1.1.4.1 Use interfaces or abstract classes to implement multi-level product structures
Factory classes can have multiple static factory methods, which are used to produce different product objects.
1.1.4.2 Multiple factory methods
are responsible for creating different product objects. For example, the java.text.DateFormat class is the factory class of its subclass, and the DateFormat class provides multiple static factory methods.
1.1.4.3 Omission of abstract product role
If the system has only one specific product role, then the abstract product role can be omitted. The simplified class diagram after omitting the abstract product role is as follows:
The following is an example, the factory role creates a specific product, the source code is as follows:
1.1.4.3.1 Product role: ConcreteProduct.java
package com .lavasoft.patterns.simplefactory.gchb;
/**
* Created by IntelliJ IDEA.
* FileName:ConcreteProduct.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 2:07:48
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Pattern - Simple Factory Pattern - Work-drawing Merger (Merging Factory Role and Abstract Product Role)
* ReadMe: Specific product category, indicating a single type of product.
*/
public class ConcreteProduct {
public ConcreteProduct() {
}
}
1.1.4.3.2 Factory role:
package com. lavasoft.patterns.simplefactory.gchb;
/**
* Created by IntelliJ IDEA.
* FileName:Creator.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 1:56:43
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Pattern - Simple Factory Pattern - Merger of Work and Drawing (Merging Factory Role and Abstract Product Role)
* ReadMe: Specific product categories are merged with abstract product roles to produce only a single type of product.
*/
public class Creator {
/**
* Static factory method
* @return a product
*/
public static Creator factory(){
return new Creator();
}
}
1.1.4.3.3 Test class
package com.lavasoft.patterns.simplefactory.gchb;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 2:11:30
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Pattern--Simple Factory Pattern--Worker Merger (Merger of Factory Role and Abstract Product Role)
* ReadMe: Worker Merger Test Class
*/
public class TestApp {
private void test() {
Creator t = Creator.factory();
System.out.println("Product successfully produced!"); public static void main(String args[]) {
;
1.1.4.4 Factory role merged with abstract role
In some cases, the factory role can be played by the abstract product role. A typical application is the java.text.DateFormat class, an abstract product class that is also a factory for subclasses, as shown in the figure below:
The following is an implementation I wrote myself, the source code is as follows:
package com.lavasoft.patterns.simplefactory.cxsl;
/**
* Created by IntelliJ IDEA.
* User: LavaSoft * Date: 2006-12-3
* Time: 3:23:47* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Pattern - Simple Factory Pattern - The merger of factory role and abstract product role* ReadMe: Abstract product class, and factory class at the same time.
*/public abstract class AbsProduct {
static Product factory(){
}
}
1.1.4.4.2 Specific product category
package com.lavasoft.patterns.simplefactory.cxsl;
/**
* Created by IntelliJ IDEA.
* FileName:Product.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 3:23:54
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* ReadMe: Specific Product Category
*/public class Product {
Product(){
}
1.1.4.4.3 Test class
package com.lavasoft.patterns.simplefactory.cxsl;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-3
* Time: 3:30:30
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* ReadMe: Test Class
*/public class TestApp {
private void test () {
System.out.println("A product object was successfully created!");
public static void main(String args[]) { TestApp test = new TestApp();
test.test();
}
}
1.1.4.4.4 Test results
Successfully created a product object!
This implementation is very simple, so the code will not be explained in detail!
1.1.4.5 All three roles are merged
If based on the above example, even the abstract product role is omitted, and the factory role can be merged with the specific product role. In other words, a product class is its own factory. As shown in the figure below:
1.1.4.5.1 Specific product category
package com.lavasoft.patterns.simplefactory.sshb;/**
* Created by IntelliJ IDEA.
* FileName:ConcreteProduct.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 2:20:38
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading notes
* Factory mode - simple factory mode - three-color-in-one mode
* ReadMe: Abstract product, product, factory category three and one specific product category
*/
public class ConcreteProduct
{
public ConcreteProduct(){}
/**
* Static factory method
* @return specific product ConcreteProduct instance
*/
public static ConcreteProduct factory()
{
return new ConcreteProduct();
}
}
1.1.4.5.2 Test class
package com.lavasoft.patterns.simplefactory.sshb;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Time: 2:24:22
* "Java and Patterns" (--Dr. Yan Hong (Author) Reading Notes
* Factory Mode – Simple Factory Mode – Three Colors in One Mode
* ReadMe: Test Method
*/
public class TestApp {
//Test method
private void test () () {
ConcreteProduct T = ConcreteProduct.factory ();
System.out.println ("Product successful production!"); stapp ()) .test();
}
}
1.1.4.5.3 Test running results
1.1.4.6 The cyclic use of product objects and registered factory methods
are discussed here in the single case mode and the multiple case mode.Advantages and disadvantages of the simple factory pattern
1.1.4.6.1 Advantages of the simple factory pattern
1.1.4.6.2 Disadvantages of the simple factory pattern
This factory class concentrates all product creation logic, forming an omnipotent class (also called the God class) that knows everything. If something goes wrong with this class, the entire application will be greatly affected.
When a product has multiple interfaces, it can be difficult to determine which product class instance to create under what conditions.For factories, adding new products is a painful process. The factory role must know each product, how to create them, and when to make them available to customers. In other words, accepting new products means modifying the source code of this factory role. Simple factories support the open-closed principle only to a limited extent.
Since the simple factory pattern uses static methods as factory methods, and static methods cannot be inherited by subclasses, the factory role cannot form a hierarchical structure based on inheritance. This shortcoming is overcome in the factory method pattern.
1.1.4.7 The application of simple factory pattern in Java
XMLReaderFactory and simple factory pattern in SAX2 library
1.1.4.8 Nuwa makes people out of clay