Welcome to today’s study, today we are going to learn the factory model. A few more words, I mentioned earlier that this month will be on Java design patterns in detail, welcome to click on the profile picture, follow my column, I will continue to update, come on!
Series of articles:
Singletons of design patterns
Without further ado, let’s get to the point
The factory pattern
I remember reading in a book that the factory pattern is divided into three types: simple factories, factory methods, and abstract factories, with a single purpose: “abstraction.” In the actual work, more often used may be the factory pattern, and abstract factory pattern these two types. This article will mainly talk about these two, simple factories will also say (relatively simple). We explore from shallow to deep, from easy to difficult.
So let’s start with a picture that’s easy to understand.
We’re going to do algorithmic operations, so define an abstract operation class, define an abstract operation method. The factory was set up. The factory has to produce products, inheriting interfaces or implementation classes to implement different algorithms. This is the classic factory pattern (no factory method pattern series escapes from this picture)
Simple factory mode
Let’s start with the simplest one. Simple factory, can not be very simple haha. The simple Factory pattern belongs to the creation pattern, also known as the Static Factory Method pattern, but does not seem to be one of the 23 design patterns.
In the simple factory pattern, a factory object determines which instances of a product class to create, that is, define an interface to create the object and let its subclasses decide which factory class to instantiate.
- Abstract class or interface: An interface (either abstract class or interface) that defines the product object to be created
- Concrete implementation: a concrete type of product with a unified parent class (ProductA…)
- Product factory: Responsible for creating product objects. The factory pattern also embodies the open closed principle, separating the part of the code that changes “create a concrete product implementation class” from the part of the code that doesn’t change “use the product,” and then extending the implementation of the factory when you want to add new products.
Code sample
Let’s imagine this scenario. (do cake), there are thousandlayer cake, soy paste cake, and spring onion cake, egg cake……
So we need to produce different kinds of cakes to meet the needs of the public:
// Step 1: abstract class or interface: defines the interface of the product object to be created.
// Step 2: implement a specific type of product with a uniform parent class (ProductA...)
// Step 3 product factory: Responsible for creating product objects. The factory pattern also embodies the open closed principle, separating the part of the code that changes "create a concrete product implementation class" from the part of the code that doesn't change "use the product," and then extending the implementation of the factory when you want to add new products.
// Define the interface ()
public interface Cake {
/ / production of bread
void productCake(a);
}
// Layer cake products
class ThousandCake implements Cake {
@Override
public void productCake(a) {
/ /... Output logic, thousand-layer cake approach;}}// Green onion cake products
class ScallionCake implements Cake {
@Override
public void productCake(a) {
/ /... Output logic, the practice of scallion cake;}}/ /... Other cakes are omitted
// The third step is to create the factory and make the pie
/** * Cake factory */
public class CakeFactory {
public Cake getInstance(int cakeType) {
if(CakeEnum.QCB.getCode() == cakeType){
/ / puff pastry
return new ThousandCake();
} else if(CakeEnum.CHB.getCode() == cakeType){
/ / chopped green onion cakes
return new ScallionCake();
}
return null;
}
/ / call
public static void main(String[] args) {
CakeFactory cakeFactory = new CakeFactory();
// Produce a thousand-layer cake
Cake thousandCake = CakeFactory.getInstance(CakeEnum.QCB.getCode());
/ /...}}Copy the code
The factory implementation above is a concrete CakeFactory class, not an interface or abstract class. The getInstance() method uses if-else to create and return a concrete cake instance. If a new cake class is added, a new if-else is added to the CakeFactory creation method. What if I do it again? I have to say if else. It’s not scalable, it’s against the open closed principle, and it affects readability. Therefore, this approach is used in cases where the business is simple and the factory class does not change often.
So in view of the above situation there is no place to improve, look down!
Factory method pattern
To solve the “adding if-else” problem mentioned above, you can create a corresponding factory subclass for each cookie class that implements the same abstract factory interface. Thus, to create different kinds of pie, you just need to implement different factory subclasses. When a new class is added, a new concrete factory inherits from the abstract factory without modifying any of the classes.
You can see that compared to the simple factory, the middle of the additional for each cookie class to establish the corresponding factory class, for the root of the factory class, these classes are also called factory subclasses.
- Abstraction factory: Declares the interface to the factory method.
- Specific product factory: The interface that implements the factory method, responsible for creating the product object.
- Product abstract class or interface: Defines the interface to the product object created by the factory method.
- Specific product implementation: A specific type of product with a unified parent class.
The code shown
// Step 1: Abstract factory: declare the interface of the factory method.
// Step 2: Concrete product factory: the interface that implements the factory method is responsible for creating the product object.
// Step 3: Product abstract class or interface: Define the interface to the product object created by the factory method.
// Step 4: Concrete product implementation: a concrete type of product with a uniform parent class.
/** ** ** ** ** ** ** ** **
public interface MachineApi {
/ / process: processing
/ / material: material
public void process(String material);
}
// Step 2: Create a concrete product factory: the interface that implements the factory method is responsible for creating the product object
/** * thousand layer cake machine */
public class ThousandCakeMachine implements MachineApi {
@Override
public void process(String material) {
System.out.println("I put" + material + "Processed into a thousand-layer cake."); }}/** * Scallion cake */
public class ScallionCakeMachine implements MachineApi {
@Override
public void process(String material) {
System.out.println("I put" + material + "Processed into a scallion cake."); }}// Step 3: Product abstract class or interface: Define the interface to the product object created by the factory method
public abstract class Factory{
/** * Let subclasses (concrete factories) instantiate concrete objects (machines) */
public abstract MachineApi newMachine(a);
/** * Processing materials */
public void process(String material){ MachineApi machine = newMachine(); machine.process(material); }}// Step 4: A specific type of product with a uniform parent class
// I need two factories to make my thousand-layer cake and my scallion cake
// The thousand-layer cake factory
public class ThousandCakeFactory extends Factory{
// For the biscuit factory, all you need to do is supply the biscuit machine
@Override
public MachineApi newMachine(a) {
return newSteamedBunMachine(); }}// Green Onion cake factory
public class ScallionCakeFactory extends Factory{
// The factory only needs to provide the machine
@Override
public MachineApi newMachine(a) {
return new BoodleMachine();
}
}
ThousandCakeFactory cakeFactoryFactory = new ThousandCakeFactory ();
cakeFactoryFactory.process("Flour");// I processed the flour into a thousand-layer cake
Copy the code
Each cake type corresponds to a factory subclass, and the different factory subclasses are instantiated when a concrete cake object is created. But if there are more and more subclasses involved in the business, should there be a factory class for each subclass? This multiplies the number of classes in the system and increases the complexity of the code.
Then scroll down to the abstract factory!
The abstract factory
Maybe some friends who see here will say, “This blogger loves eating cakes, why do you keep talking about cakes? Ha ha, well, let’s not talk about cakes. Let’s talk about our popular domestic brands” Li Ning “and” Hongxing Erke “.
If you look at this diagram, a design pattern like this, which groups product classes, where different products in the group are implemented in different ways by the same factory class, is the abstract factory pattern.
Abstract factories are suitable for:
- When a system is independent of the creation, composition, and presentation of its products;
- When a system is to be configured by one of multiple product families;
- To emphasize the design of a series of related product objects for joint use;
- When you provide a library of product classes and only want to show their interface rather than their implementation;
The code shown
/ / clothes
public interface clothes {
void dressClothes(a);
}
// Hongxing Erke brand clothes
public class HXEKbrandClothes implements clothes {
@Override
public void dressClothes(a) {}}// Li Ning clothes
public class LiNBrandClothes implements clothes {
@Override
public void dressClothes(a) {}}/ / shoes
public interface Shoes {
void dressShoes(a);
}
// Wear hongxing Erke brand shoes
public class HXEKbrandShoes implements Shoes {
@Override
public void dressShoes(a) {
// Wearing hongxing Erke brand}}// Wear Li Ning shoes
public class LiNBrandShoes implements Shoes {
@Override
public void dressShoes(a) {
// Wearing Li Ning}}/ / trousers
public interface Pants {
void dressPants(a);
}
// Wear pants of Hongxing Erke brand
public class HXEKbrandPants implements Pants {
@Override
public void dressPants(a) {
// Wearing hongxing Erke brand}}// Wear Li Ning pants
public class LiNBrandPants implements Pants {
@Override
public void dressPants(a) {
// Wearing Li Ning}}// Factory class. The factory is divided into Hongxing Erke factory and Li Ning factory, each responsible for the creation of products within the brand
public interface IFactory {
Pants createPants(a);
Shoes createShoes(a);
clothescreateClothes(a);
}
// Hongxing Erke
public class HXEKFactory implements IFactory {
@Override
public Pants createPants(a){
Pants pants = new Pants();
// Make a pair of trousers
return pants;
}
@Override
public Shoes createShoes(a){
Shoes shoes = new Shoes();
// Make a pair of shoes
return shoes;
}
@Override
publicclothescreateClothes(a){
Clothes clothes = new Clothes();
/ /... Make coat;
returnclothes; }}// Li Ning Factory
public class LiNFactory implements IFactory {
@Override
public Pants createPants(a){
Pants pants = new Pants();
// Make a pair of trousers
return pants;
}
@Override
public Shoes createShoes(a){
Shoes shoes = new Shoes();
// Make a pair of shoes
return shoes;
}
@Override
publicclothescreateClothes(a){
Clothes clothes = new Clothes();
/ /... Make coat;
returnclothes; }}// The client code. Instantiating different factory subclasses can create different products through different creation methods
public class Main {
public static void main(String[] args) {
IFactory liNFactory = new LiNFactory();
IFactory hxekFactory = new HXEKFactory();
// Create hongxing Erke jacket
Clothes hxekClothes = hxekFactory.createClothes();
/ /...}}Copy the code
OK, the end of this chapter, we will see you next time, see here, thank you for reading, if you think it is helpful to you, please like the collection and attention!
I have included this chapter in my project, click on the project below, and follow the column. I will publish dry items every day, and I will continue to enter design patterns this month.
I beg your attention again. It’s not easy to create. It’s 10:30 now and I’m still in the company. Come on! See you next time