Several forms of the factory pattern
The factory pattern is specifically responsible for instantiating a large number of classes that have a common interface. Factory patterns can dynamically decide which classes to instantiate, without having to know in advance which classes to instantiate each time. Factory patterns have the following forms:
- Simple Factory Pattern: Also known as static Factory method pattern
- Factory Method pattern: Also known as polymorphic Factory pattern
- Abstract Factory pattern: Also known as toolbox pattern
Simple Factory model
The sample
There is a farm, specialized to sell a variety of fruits, now need the following several fruits: apple, grape, strawberry define a fruit interface, all fruits must implement:
public interface Fruit {
/ * * * / growth
void grow(a);
/ * * * / harvest
void harvest(a);
/ * * * / planting
void plant(a);
}
Copy the code
Apple:
public class Apple implements Fruit {
/** The age of the apple tree */
private int treeAge;
@Override
public void grow(a) {
System.out.println("Apples are growing...");
}
@Override
public void harvest(a) {
System.out.println("The apples have been harvested!);
}
@Override
public void plant(a) {
System.out.println("The apples have been planted!);
}
/** Auxiliary methods */
public static void log(String msg) {
System.out.println(msg);
}
/** The age of apple tree */
public int getTreeAge(a) {
return treeAge;
}
/** Apple tree age assignment method */
public void setTreeAge(int treeAge) {
this.treeAge = treeAge; }}Copy the code
Grape class:
public class Grape implements Fruit {
/** has no seed */
private boolean seedless;
@Override
public void grow(a) {
System.out.println("Grapes are growing...");
}
@Override
public void harvest(a) {
System.out.println("The grapes have been harvested!);
}
@Override
public void plant(a) {
System.out.println("The grapes are planted!);
}
/** Auxiliary methods */
public static void log(String msg) {
System.out.println(msg);
}
/** there is a seedless method */
public boolean isSeedless(a) {
return seedless;
}
/** There are seedless assignment methods */
public void setSeedless(boolean seedless) {
this.seedless = seedless; }}Copy the code
Strawberry class:
public class Strawberry implements Fruit {
@Override
public void grow(a) {
System.out.println("Strawberries are growing...");
}
@Override
public void harvest(a) {
System.out.println("The strawberries have been harvested!);
}
@Override
public void plant(a) {
System.out.println("Strawberries are planted!");
}
/** Auxiliary methods */
public static void log(String msg) { System.out.println(msg); }}Copy the code
There was also a gardener who took care of the fruit in all its cases:
public class Farm {
public static Fruit factory(String which) {
if (which.equalsIgnoreCase("apple")) {
Apple apple = new Apple();
apple.plant();
return apple;
} else if (which.equalsIgnoreCase("grape")) {
Grape grape = new Grape();
grape.plant();
return grape;
} else if (which.equalsIgnoreCase("strawberry")) {
Strawberry strawberry = new Strawberry();
strawberry.plant();
return strawberry;
} else {
System.out.println("No such fruit!");
return null; }}}Copy the code
The test class:
public class Client {
public static void main(String[] args) {
Farm.factory("apple");
Farm.factory("grape");
Farm.factory("strawberry"); }}Copy the code
structure
Roles involved:
- Factory Class (Creator) role: This role is the core of the factory method pattern, containing the business logic that is closely related to the application. The factory class creates product objects under direct invocation from the client and is implemented by a Java concrete class
- Abstract Product role: The class that plays this role is the parent class, or interface, of the objects created by the factory method pattern
- ConcreteProduct role: any object created by the factory method pattern is an instance of this role
Source code is as follows:
public class Creator {
/** Static factory method */
public static Product factory(a) {
return newConcreteProduct(); }}Copy the code
public interface Product {}Copy the code
public class ConcreteProduct implements Product {}Copy the code
The advantages and disadvantages
Advantages:
- A caller who wants to create an object needs only to know its name
- High scalability. If you want to add a product, just extend a factory class
- Masking the concrete implementation of the product, the caller only cares about the interface of the product
Disadvantages: Every time a product is added, a concrete class and object implementation factory need to be added, which doubles the number of classes in the system, increasing the complexity of the system to a certain extent, but also increasing the dependence of concrete classes in the system
Nuwa kneaded the earth to make people
There are several important roles in this process:
- Nuwa is a factory class, which is the core of the simple factory model
- Abstract people, is an idea of Nu Wa, nu Wa in accordance with this idea, created a specific person, they are compound the definition of the abstract person
- Concrete people, such as Tom, Tom, etc., are concrete product roles in simple factories
Factory role: Nu Wa, responsible for making babies:
public class NuwaFactory {
public static People people(String name) {
if (name.equalsIgnoreCase("zhangSan")) {
System.out.println("Nu Wa made a man, and a man named Zhang SAN came out.");
return new ZhangSan();
} else if (name.equalsIgnoreCase("lisi")) {
System.out.println("Nu Wa made a man, and a Li Si came out.");
return new LiSi();
} else {
return null; }}}Copy the code
An abstract person with the functions of eating, sleeping, and talking:
public interface People {
/ * * * / for dinner
void eat(a);
/ * * * / sleep
void sleep(a);
/ * * * / speaking
void speak(a);
}
Copy the code
Specific people, Zhang SAN, Li Si:
public class ZhangSan implements People {
@Override
public void eat(a) {
System.out.println("Joe is eating.");
}
@Override
public void sleep(a) {
System.out.println("Joe is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Joe is talking."); }}Copy the code
public class LiSi implements People {
@Override
public void eat(a) {
System.out.println("Li Si is eating.");
}
@Override
public void sleep(a) {
System.out.println("Tom is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Tom Is talking."); }}Copy the code
The test class:
public class Client {
public static void main(String[] args) {
NuwaFactory.people("zhangSan");
NuwaFactory.people("lisi"); }}Copy the code
Factory method pattern
The intent of the factory method pattern is to define a factory interface for creating product objects, deferring the actual creation to subclasses
The result of further abstraction makes it possible to introduce new products without modifying the specific factory roles
structure
Roles involved:
- Abstract Factory (Creator) role: This role is the core of the factory method pattern, and any factory class that creates objects in the pattern must implement this interface
- ConcreteCreator role: The ConcreteCreator role is a concrete Java class that implements an abstract factory interface. The ConcreteCreator role contains application-specific logic and is called by the application to create product objects
- Abstract Product roles: Supertypes of objects created by the factory method pattern, common superclasses of Product objects, or shared interfaces
- ConcreteProduct role: this role implements the interface declared by the abstract product role, and each object created by the factory method pattern is an instance of a ConcreteProduct role
The source code is as follows:
public interface Creator {
/** Factory method */
Product factory(a);
}
Copy the code
public class ConcreteCreator1 implements Creator {
@Override
public Product factory(a) {
return newConcreteProduct1(); }}Copy the code
public class ConcreteCreator2 implements Creator {
@Override
public Product factory(a) {
return newConcreteProduct2(); }}Copy the code
public interface Product {}Copy the code
public class ConcreteProduct1 implements Product {}Copy the code
public class ConcreteProduct2 implements Product {}Copy the code
Nuwa lifted a rope to make a man
Then, she realized that she couldn’t make all of them in this way, so she came up with a clever solution. She used a rope, stirred it in the muddy water, and then shook it. All the mud spots turned into peopleAbstract factory, which merely states the method of making people by lifting ropes:
public interface NuwaFactory {
/** make a man */
People ropeMadePeople(a);
}
Copy the code
Specific factory, sun rope and Yin rope:
public class Man implements NuwaFactory {
@Override
public People ropeMadePeople(a) {
System.out.println("Make a baby with a string.");
return newZhangSan(); }}Copy the code
public class Woman implements NuwaFactory {
@Override
public People ropeMadePeople(a) {
System.out.println("Make a man with a black rope.");
return newXiaoHong(); }}Copy the code
Abstract product that declares some human behavior:
public interface People {
/ * * * / for dinner
void eat(a);
/ * * * / sleep
void sleep(a);
/ * * * / speaking
void speak(a);
}
Copy the code
Specific product roles: Zhang SAN and Xiao Hong:
public class ZhangSan implements People {
@Override
public void eat(a) {
System.out.println("Joe is eating.");
}
@Override
public void sleep(a) {
System.out.println("Joe is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Joe is talking."); }}Copy the code
public class XiaoHong implements People {
@Override
public void eat(a) {
System.out.println("Little Red is eating.");
}
@Override
public void sleep(a) {
System.out.println("Little Red is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Red is talking."); }}Copy the code
The test class:
public class Client {
public static void main(String[] args) {
NuwaFactory man = new Man();
NuwaFactory woman = newWoman(); man.ropeMadePeople(); woman.ropeMadePeople(); }}Copy the code
Abstract Factory pattern
Abstract factory pattern is the most abstract and general of all factory patterns
structure
Roles involved:
- Abstract Factory role: This role is the core of the Factory method pattern, and all concrete Factory classes must implement the Java interface or inherit the Abstract Java class
- Concrete Factory role: This role creates the instance of the product directly on the call from the client, and this role contains the logic to select the appropriate product object
- Abstract Product role: The class that plays this role is the parent of the objects created by the factory method pattern, or the interfaces they share
- Concrete Product Roles: Each object created by the abstract factory pattern is an instance of a Concrete Product role
The source code is as follows:
public interface Creator {
/** Factory method for product A */
ProductA factoryA(a);
/** Factory method for product B */
ProductB factoryB(a);
}
Copy the code
public class ConcreteCreator1 implements Creator {
@Override
public ProductA factoryA(a) {
return new ProductA1();
}
@Override
public ProductB factoryB(a) {
return newProductB1(); }}Copy the code
public class ConcreteCreator2 implements Creator {
@Override
public ProductA factoryA(a) {
return new ProductA2();
}
@Override
public ProductB factoryB(a) {
return newProductB2(); }}Copy the code
public interface ProductA {}Copy the code
public class ProductA1 implements ProductA {}Copy the code
public class ProductA2 implements ProductA {}Copy the code
public interface ProductB {}Copy the code
public class ProductB1 implements ProductB {}Copy the code
public class ProductB2 implements ProductB {}Copy the code
Nuwa made all things
In this story, nu Wa’s products are divided into two ways, one is according to the product is human or animal to divide, one is according to the product is male and female, male and female to divide
-
The Magic rope interface acts as an abstract factory
-
Human interface as human abstract role, animal interface as animal abstract role
-
Yin rope and Yang rope inherit from the divine rope interface, which is a specific rope class
-
Adam and Eve are concrete human beings, and the ox and mare are concrete animals
Abstract factory:
public interface NuwaGodRope {
/** God made man */
People ropeMadePeople(a);
/** ** ** /
Animal ropeMadeAnimal(a);
}
Copy the code
Specific roles of factory:
public class YangRope implements NuwaGodRope {
@Override
public People ropeMadePeople(a) {
System.out.println("Nuwa made Adam.");
return new Adam();
}
@Override
public Animal ropeMadeAnimal(a) {
System.out.println("Nuwa made a bull.");
return newTheBull(); }}Copy the code
public class YinRope implements NuwaGodRope {
@Override
public People ropeMadePeople(a) {
System.out.println("Nuwa made Eve.");
return new Eve();
}
@Override
public Animal ropeMadeAnimal(a) {
System.out.println("Nuwa made a mare.");
return newMare(); }}Copy the code
Human Interface:
public interface People {
/ * * * / for dinner
void eat(a);
/ * * * / sleep
void sleep(a);
/ * * * / speaking
void speak(a);
}
Copy the code
A specific product, i.e. a specific person:
public class Adam implements People {
@Override
public void eat(a) {
System.out.println("Adam is eating.");
}
@Override
public void sleep(a) {
System.out.println("Adam is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Adam is talking."); }}Copy the code
public class Eve implements People {
@Override
public void eat(a) {
System.out.println("Eve is eating.");
}
@Override
public void sleep(a) {
System.out.println("Eve is sleeping.");
}
@Override
public void speak(a) {
System.out.println("Eve speaks."); }}Copy the code
Animal interface:
public interface Animal {
/ * * * / for dinner
void eat(a);
/ * * * / sleep
void sleep(a);
Call / * * * /
void call(a);
}
Copy the code
2. A specific animal:
public class TheBull implements Animal {
@Override
public void eat(a) {
System.out.println("The bulls are looking for food.");
}
@Override
public void sleep(a) {
System.out.println("The bull is sleeping.");
}
@Override
public void call(a) {
System.out.println("The bull is bleating."); }}Copy the code
public class Mare implements Animal {
@Override
public void eat(a) {
System.out.println("The mare is foraging.");
}
@Override
public void sleep(a) {
System.out.println("The mare is sleeping.");
}
@Override
public void call(a) {
System.out.println("The mare is bleating."); }}Copy the code
The test class:
public class Client {
public static void main(String[] args) {
NuwaGodRope yangRope = new YangRope();
NuwaGodRope yinRope = newYinRope(); People adam = yangRope.ropeMadePeople(); adam.sleep(); System.out.println(); Animal theBull = yangRope.ropeMadeAnimal(); theBull.call(); System.out.println(); People eve = yinRope.ropeMadePeople(); eve.eat(); System.out.println(); Animal mare = yinRope.ropeMadeAnimal(); mare.sleep(); }}Copy the code