The abstract factory pattern of design pattern learning

Abstract factory pattern

Provide an interface for creating a series of related or interdependent objects without specifying their specific classes. It is an object creation mode

Class Diagram

Insert picture description here
AbstractProductA and AbstractProductB are two abstract products

ConcreteProduct is the realization of the concrete classification of two abstract products

AbstractFacroty is an abstract factory interface, which contains all abstract methods for product creation, and ConcreteFactory is a concrete factory

Application example A
software company wants to develop a set of interface skin library, which can beautify the interface of Java-based desktop software. The user can select the skin through the menu when using it. Different skins will provide buttons, text boxes, combo boxes and other interface elements with different visual effects. For example, a Spring style skin will provide light green buttons and text with green borders. A combo box with a box and a green border, while the Summer style skin provides a light blue button, a text box with a blue border, and a combo box with a blue border. The schematic diagram of the structure is shown in the following figure:
Insert picture description here

The skin library needs to have good flexibility and scalability, users can freely choose different skins, and developers can add new skins without modifying the existing code.
The abstract factory pattern is now used to design the interface skin library.
Insert picture description here

Code

Button interface, abstract product

package design.abstractfactory;

public interface Button {
    
    

	public void display();
}

Specific products under the button interface

package design.abstractfactory;

public class SpringButton implements Button {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示浅绿色按钮.");

	}

}

package design.abstractfactory;

public class SummerButton implements Button {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示浅蓝色按钮.");

	}
}

Text box interface, abstract product

package design.abstractfactory;

public interface TextField {
    
    

	public void display();
}

Specific products under the text box interface

package design.abstractfactory;

public class SpringTextField implements TextField {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示绿色边框文本框.");

	}

}

package design.abstractfactory;

public class SummerTextField implements TextField {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示蓝色边框文本框.");

	}

}

Combo box interface, abstract product

package design.abstractfactory;

public interface ComboBox {
    
    

	public void display();
}

Specific products under the combo box interface

package design.abstractfactory;

public class SpringComboBox implements ComboBox {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示绿色边框组合框.");

	}

}

package design.abstractfactory;

public class SummerComboBox implements ComboBox {
    
    

	@Override
	public void display() {
    
    
		System.out.println("显示蓝色边框组合框.");

	}
}

Interface skin interface, acting as an abstract factory

package design.abstractfactory;

public interface SkinFactory {
    
    

	public Button createButton();

	public TextField createTextField();

	public ComboBox createComboBox();
}

Specific factory

package design.abstractfactory;

public class SpringSkinFactory implements SkinFactory {
    
    

	@Override
	public Button createButton() {
    
    
		return new SpringButton();
	}

	@Override
	public TextField createTextField() {
    
    
		return new SpringTextField();
	}

	@Override
	public ComboBox createComboBox() {
    
    
		return new SpringComboBox();
	}

}

package design.abstractfactory;

public class SummerSkinFactory implements SkinFactory {
    
    

	@Override
	public Button createButton() {
    
    
		return new SummerButton();
	}

	@Override
	public TextField createTextField() {
    
    
		return new SummerTextField();
	}

	@Override
	public ComboBox createComboBox() {
    
    
		return new SummerComboBox();
	}

}

Configuration file config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<className>design.abstractfactory.SpringSkinFactory</className> 
</config>

Tools

package design.abstractfactory;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLUtil {
    
    

	public static Object getBean() {
    
    
		try {
    
    
			// 创建DOM文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;
			doc = builder.parse(new File("src//design//abstractfactory//config.xml"));
			// 获取包含类名的文本节点
			NodeList nl = doc.getElementsByTagName("className");
			Node classNode = nl.item(0).getFirstChild();
			String cName = classNode.getNodeValue();

			// 通过类名生成实例对象
			Class c = Class.forName(cName);
			Object obj = c.newInstance();
			return obj;
		} catch (Exception e) {
    
    
			e.printStackTrace();
			return null;
		}
	}
}

Client

package design.abstractfactory;

public class Client {
    
    

	public static void main(String[] args) {
    
    
		// 使用抽象层定义
		SkinFactory factory;
		//SkinFactory factory1;
		Button bt;
		TextField tf;
		ComboBox cb;
		factory=(SkinFactory) XMLUtil.getBean();
		
		bt=factory.createButton(); 
		tf=factory.createTextField();
		 
		cb = factory.createComboBox();
		bt.display();
		tf.display();
		cb.display();
	}
}

Insert picture description here
If you need to change the skin, just modify the configuration file

If there is a project that needs to use the spring style drop-down list box with the summer style text box and button, how to complete it, try to achieve it in the above project

Add new concrete factory class

package design.abstractfactory;

public class SpringSummerSkinFactory implements SkinFactory {
    
    

	@Override
	public Button createButton() {
    
    
		return new SummerButton();
	}

	@Override
	public TextField createTextField() {
    
    
		return new SummerTextField();
	}

	@Override
	public ComboBox createComboBox() {
    
    
		return new SpringComboBox();
	}

}

Replace the reference of the configuration file with the factory class

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<className>design.abstractfactory.SpringSummerSkinFactory</className>
</config>

The result of running the client is
Insert picture description here

Advantages and disadvantages of abstract factory pattern

Advantages :
(1) Isolate the generation of specific classes, so that the client does not need to know what is created
(2) When multiple objects in a product family are designed to work together, it can ensure that the client always only uses the same An object in a product family
(3) It is convenient to add a new product family, no need to modify the existing system, in line with the principle of opening and closing

Disadvantages : It
is troublesome to add a new hierarchical structure, need to make major changes to the original system, and even need to modify the abstract layer code, which violates the principle of opening and closing

Applicable environment

(1) A system should not depend on the details of how product class instances are created, combined, and expressed
(2) There are more than one product family in the system, and only one product family is used each time
(3) belongs to the same product The products of the family will be used together. This constraint must be reflected in the design of the system.
(4) The product level structure is stable. After the design is completed, no new product level structure will be added to the system or the existing product level structure will not be deleted.

Comparison between factory method and abstract factory

The factory method generally only produces one kind of product. The core is to define abstract methods to create specific products through subclasses. Different subclasses produce different products; the abstract factory produces a set of products, and each factory subclass needs to produce a set of products. , And each product has a different concrete type in each sub-category; the
factory method lurks in the abstract factory. This makes sense, because the task of the abstract factory is to define the interface responsible for creating a set of products, and each method of this interface is responsible for creating a specific product, so let the subclasses of the factory implement these methods. For example, for SkinFactory, if we only look at one type of component: button, the method createButton() is defined in the factory interface, and the subclass implements this method to create buttons of different styles, that is, "the subclass decides what to be instantiated Which one is the class", fully conforms to the definition of the factory method.

Specific performance : The factory method has only one abstract method, and the abstract factory has a large interface (or multiple abstract methods);

Common points : the
principle of dependency inversion: all rely on abstraction, not concrete classes;
class explosion: especially abstract factories, which will significantly increase the number of classes;

Applicable scenarios :

Abstract Factory: It is applicable when you need to create a product family and want to make related products to be manufactured together.
Factory method: When creating a product, alternatively, you can decouple your customer code from the concrete classes that need to be instantiated. Or, you can use it if you don't know which classes need to be instantiated in the future.

Small summary

Whether it is a simple factory pattern, a factory method pattern, or an abstract factory pattern, they all belong to the factory pattern, and they are very similar in form and characteristics. Their ultimate goal is to decouple.

Refer to the
java design pattern

Nuggets: https://juejin.cn/post/6844903783680442381

Nuggets: https://juejin.cn/post/6844903895760650254

Guess you like

Origin blog.csdn.net/qq_43610675/article/details/111407140