Spring framework learning section 2: Design Patterns

This blog is used for personal learning. It comes from the book of ssm framework, and makes an arrangement of knowledge points.

2.4 factory mode and abstract factory mode

Instead of creating objects in the way of new, define a module similar to a factory, and find the corresponding factory according to the customer's needs to produce the required products. Especially for the customer, the factory is just an abstract concept, he just knows that there is such a factory to meet his needs.

2.4.1 Simple Factory mode

The following figure shows the product factory mode:

As can be seen from the above figure, there is an IProduct interface, under which there are five implementation classes, Product1, Product2, Product3, Product4 and Product5. They belong to a large class and can be managed through a factory. However, due to different types, initialization is different. In order to facilitate management, use the product factory class to create the objects of these products. Users can determine what products they need through some features of the products, such as product number. We can look at the pseudo code of the product factory:

public class ProductFactory{
	public static IProduct createProduct(String productNo){
		switch(productNo){
			case "1": return new Product1(xxxx);
			case "2": return new Product2(xxxx);
			case "3": return new Product3(xxxx);
			case "4": return new Product4(xxxx);
			case "5": return new Product5(xxxx);
			default : throw new NotSupportedException("Production of this number is not supported");
		}
	}
}

For program callers, they only need to know that the corresponding product can be obtained by specifying the product number through the createProduct method of the factory, and the product meets the specification of the interface IProduct, so initialization is much easier.

2.4.2 Abstract Factory mode

For ordinary factories, it solves the problem of creating a class of objects, but sometimes the objects are very complex, there may be dozens of types, and they can be divided into several categories. If there is only one factory, facing so many products, the logic that this factory needs to implement is too complex, so we hope to divide the factory into several parts to facilitate the maintenance of the factory's product rules. However, for callers, it is only necessary to know that there is a unified factory.

The customer just thinks that there is a factory that can produce all kinds of products, and it can produce the products I need. The factory here is only a virtual concept, not a real existence. It is actually realized by each branch factory. This virtual factory is called abstract factory, and its branches are called concrete factories. An interface specification (IProductFactory) needs to be specified. All concrete factories and abstract factories need to implement this interface.

public interface IProductFactory{
	public IProduct createProduct(String productNo);
}

The method createProduct here is implemented by every factory, including abstract factory and concrete factory.

public class ProductFactory1 implements IProductFactory{
	public IProduct createProduct(String productNo){
		IProduct product = xxxx;//The production rules of factory 1 can be the rules of a class of products
		return product;
	}
}

public class ProductFactory2 implements IProductFactory{
	public IProduct createProduct(String productNo){
		IProduct product = xxxx;//The production rules of factory 2 can be the rules of a class of products
		return product;
	}
}

public class ProductFactory3 implements IProductFactory{
	public IProduct createProduct(String productNo){
		IProduct product = xxxx;//The rules for factory 3 to produce products can be the rules for a class of products
		return product;
	}
}

At this time, we need to define an abstract factory to manage the above three specific factories. We need to define some product rules, such as using Factory 1 to create objects when the number starts with 1.

public class ProductFactory implements IProductFactory{
	public static IProduct createProduct(String productNo){
		char ch = productNo.charAt(0);
		IProductFactory factory = null;
		if(ch == '1'){
			factory = new ProductFactory1();
		}else if(ch == '2'){
			factory = new ProductFactory2();
		}else if(ch == '3'){
			factory = new ProductFactory3();
		}
		if(factory != null){
			return factory.createProduct(productNo);
		}
		return null;
	}
}

In this way, product objects can be created by product number. Creating objects is much easier for callers. Each factory only needs to maintain the production of its type of product objects, and the specific factory rules will not be particularly complex and difficult to maintain.

Added by s.eardley on Tue, 16 Jun 2020 10:19:56 +0300