preface
Software Design Pattern, also known as design pattern, is a summary of code design experience that is repeatedly used, known by most people, classified and catalogued. It describes some recurring problems in the software design process and the solutions to the problems.
In other words, it is a series of routines to solve specific problems and a summary of the code design experience of predecessors. It is universal and can be used repeatedly.
Its purpose is to improve the reusability, readability and reliability of the code.
1, Singleton mode
1. Singleton mode definition
Definition of Singleton pattern: a pattern in which a class has only one instance and the class can create the instance itself
2. Implementation method of singleton mode
- Lazy mode:
/** * @author hz * @version 1.0 */ public class Singleton { private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ //If it has not been instantiated, instantiate one and return if(instance == null){ instance = new Singleton(); } return instance; } }
Lazy Mode Optimization:
/** * @author hz * @version 1.0 */ public class Singleton { private static Singleton instance = null; private Singleton(){} public static synchronized Singleton getInstance(){ //If it has not been instantiated, instantiate one and return if(instance == null){ instance = new Singleton(); } return instance; } }
- Hungry man model
/** * @author hz * @version 1.0 */ public class Singleton { //When the class is loaded, instance already points to an instance private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }
- Double check lock:
/** * @author hz * @version 1.0 */ public class Singleton { private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } }
- Static inner class:
/** * @author hz * @version 1.0 */ public class Singleton { private static class SingletonHolder{ private static Singleton instance = new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return SingletonHolder.instance; } }
- enumeration
/** * @author hz * @version 1.0 */ public enum Singleton { INSTANCE; }
3. Advantages and disadvantages of singleton mode:
- advantage:
Singleton mode can ensure that there is only one instance in memory and reduce the memory overhead.
Multiple occupation of resources can be avoided.
Set global access points in singleton mode to optimize and share resource access.
- Disadvantages:
The singleton mode generally has no interface and is difficult to expand. If you want to expand, there is no second way except to modify the original code, which violates the opening and closing principle.
In concurrent testing, singleton mode is not conducive to code debugging. During debugging, if the code in the singleton is not executed, a new object cannot be simulated.
The function code of singleton mode is usually written in a class. If the function design is unreasonable, it is easy to violate the principle of single responsibility.
4. Application scenario of singleton mode:
For Java, the singleton pattern ensures that there is only a single instance in a JVM.
The application scenarios of singleton mode mainly include the following aspects:
For some classes that need to be created frequently, using singleton can reduce the memory pressure of the system and reduce GC.
A class only requires the generation of an object, such as the monitor in a class, the ID number of everyone.
Some classes occupy more resources when creating instances, or instantiation takes a long time and is often used.
When a class needs frequent instantiation and the created objects are frequently destroyed, such as multi-threaded thread pool, network connection pool, etc.
Objects that frequently access databases or files.
For some control hardware level operations, or from the system point of view, they should be single control logic operations. If there are multiple instances, the system will be completely disordered.
When objects need to be shared. Since singleton mode allows only one object to be created, sharing the object can save memory and speed up object access. Such as the configuration object in the Web, the connection pool of the database, etc.
2, Factory mode
1. Simple factory mode
-
definition:
We call the created object "product" and the object that creates the product "factory". If there are not many products to be created, only one factory class can be completed. This mode is called "simple factory mode".
The method of creating an instance in the simple factory pattern is usually static
Therefore, Simple Factory Pattern is also called Static Factory Method Pattern. -
Composition of simple factory mode:
① Simple factory: it is the core of the simple factory pattern and is responsible for implementing the internal logic of creating all instances. The method of creating product class of factory class can be directly called by the outside world to create the required product object.
② Abstract Product: it is the parent class of all objects created by a simple factory and is responsible for describing the common interface shared by all instances.
③ Concrete product: it is the creation target of simple factory mode. -
Structure diagram
-
Java code
/** * @author hz * @version 1.0 */ public class Client { //Abstract product public interface Product { void show(); } //Specific product: ProductA static class ConcreteProduct1 implements Product { public void show() { System.out.println("Specific product 1 display..."); } } //Specific product: ProductB static class ConcreteProduct2 implements Product { public void show() { System.out.println("Specific product 2 display..."); } } final class Const { static final int PRODUCT_A = 0; static final int PRODUCT_B = 1; static final int PRODUCT_C = 2; } static class SimpleFactory { public static Product makeProduct(int kind) { switch (kind) { case Const.PRODUCT_A: return new ConcreteProduct1(); case Const.PRODUCT_B: return new ConcreteProduct2(); } return null; } } }
- Advantages and disadvantages:
advantage:
① The factory class contains the necessary logical judgment to decide when to create an instance of which product. The client can avoid the responsibility of directly creating product objects and easily create corresponding products. The responsibilities of the factory and products are clearly distinguished.
② The client does not need to know the class name of the specific product created, but only needs to know the parameters.
③ You can also import a configuration file to replace and add new specific product classes without modifying the client code.
Disadvantages:
① The factory class of simple factory mode is single, which is responsible for the creation of all products. The responsibility is too heavy. Once it is abnormal, the whole system will be affected. Moreover, the factory class code will be very bloated and violate the principle of high aggregation.
② Using the simple factory mode will increase the number of classes in the system (introduce new factory classes), and increase the complexity and understanding difficulty of the system
③ It is difficult to expand the system. Once new products are added, the factory logic has to be modified. When there are many product types, the logic may be too complex
④ The simple factory mode uses the static factory method, which makes the factory role unable to form an inheritance based hierarchical structure
2. Factory method model
-
Main roles:
① Abstract Factory: it provides an interface for creating products, through which the caller accesses the factory method newProduct() of a specific factory to create products.
② Concrete factory: it mainly implements the abstract methods in the abstract factory and completes the creation of specific products.
③ Abstract Product: it defines the specification of the Product and describes the main characteristics and functions of the Product.
④ Concrete product: it implements the interface defined by the abstract product role, which is created by the specific factory and corresponds to the specific factory one by one. -
Structure diagram
-
java code
/** * @author hz * @version 1.0 */ public class AbstractFactoryTest { public static void main(String[] args) { try { Product a; AbstractFactory af; af = (AbstractFactory) ReadXML.getObject(); //Abstract factory contents are put into external configuration files, such as xml/properties, and loaded through I/O streams to create abstract factories a = af.newProduct(); a.show(); } catch (Exception e) { System.out.println(e.getMessage()); } } } //Abstract product: provides the interface of the product interface Product { public void show(); } //Concrete product 1: implement abstract methods in abstract products class ConcreteProduct1 implements Product { public void show() { System.out.println("Specific product 1 display..."); } } //Concrete product 2: implement abstract methods in abstract products class ConcreteProduct2 implements Product { public void show() { System.out.println("Specific product 2 display..."); } } //Abstract factory: provides the generation method of factory products interface AbstractFactory { public Product newProduct(); } //Specific factory 1: the generation method of factory products is realized class ConcreteFactory1 implements AbstractFactory { public Product newProduct() { System.out.println("Specific factory 1 generation-->Specific products 1..."); return new ConcreteProduct1(); } } //Specific factory 2: the generation method of factory products is realized class ConcreteFactory2 implements AbstractFactory { public Product newProduct() { System.out.println("Specific plant 2 generation-->Specific products 2..."); return new ConcreteProduct2(); } }
import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; /** * @author hz * @version 1.0 */ public class ReadXML { //This method is used to extract the specific class name from the XML configuration file and return an instance object public static Object getObject() { try { //Create document object DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("src/FactoryMethod/config1.xml")); //Gets the text node containing the class name NodeList nl = doc.getElementsByTagName("className"); Node classNode = nl.item(0).getFirstChild(); String cName = "FactoryMethod." + classNode.getNodeValue(); //System.out.println("new class name:" + cName); //Generate an instance object from the class name and return it Class<?> c = Class.forName(cName); Object obj = c.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); return null; } } }
- Advantages and disadvantages
advantage:
① Users only need to know the name of the specific factory to get the desired product, without knowing the specific creation process of the product.
② Flexibility is enhanced. For the creation of new products, you only need to write one more corresponding factory class.
③ Typical decoupling framework. The high-level module only needs to know the abstract class of the product, does not need to care about other implementation classes, and meets the Demeter rule, dependency inversion principle and Richter substitution principle.
Disadvantages:
① The number of classes is easy to be too many, which increases the complexity
② It increases the abstraction and understanding difficulty of the system
③ Abstract products can only produce one product, which can be solved by using abstract factory mode.
3. Abstract factory pattern
-
definition
Abstract factory pattern is a pattern structure that provides an interface for an access class to create a group of related or interdependent objects, and the access class can obtain different levels of products of the same family without specifying the specific class of the product -
Using the abstract factory pattern requires the following conditions:
① There are multiple product families in the system. Each specific factory creates products of the same family but belonging to different hierarchical structures.
② The system can only consume one family of products at a time, that is, the products of the same family can be used together -
Main role
As an upgraded version of the factory method pattern, the composition of the abstract factory pattern is the same as that of the factory method pattern. It is also composed of four elements: abstract factory, concrete factory, abstract product and concrete product. However, the number of methods in the abstract factory is different, and the number of abstract products is also different. -
Structure diagram
-
code
/** * @author hz * @version 1.0 */ public class FarmTest { public static void main(String[] args) { try { Farm f; Animal a; Plant p; //Read the corresponding configuration information for the production plant f = (Farm) ReadXML.getObject(); a = f.newAnimal(); p = f.newPlant(); a.show(); p.show(); } catch (Exception e) { System.out.println(e.getMessage()); } } } //Abstract products: Animals interface Animal { public void show(); } //Specific products: Horses class Horse implements Animal { public Horse() { System.out.println("Generation of specific horses"); } public void show() { System.out.println("Perform corresponding operations for horses"); } } //Specific products: Cattle class Cattle implements Animal { public Cattle() { //Generation of specific cattle System.out.println("Generation of specific cattle"); } public void show() { System.out.println("Perform corresponding operations for horses"); } } //Abstract products: Plants interface Plant { public void show(); } //Specific products: Fruits class Fruitage implements Plant { public Fruitage() { System.out.println("Specific fruit generation"); } public void show() { System.out.println("Perform corresponding operations for fruits"); } } //Specific products: Vegetables class Vegetables implements Plant { public Vegetables() { System.out.println("Specific vegetable generation"); } public void show() { System.out.println("Perform the corresponding operations of vegetables"); } } //Abstract factory: Farm class interface Farm { public Animal newAnimal(); public Plant newPlant(); } //Specific factory: Farm 1 class SGfarm implements Farm { public Animal newAnimal() { System.out.println("A new cow is born!"); return new Cattle(); } public Plant newPlant() { System.out.println("Vegetables grow!"); return new Vegetables(); } } //Specific factory: Farm 2 class SRfarm implements Farm { public Animal newAnimal() { System.out.println("The new horse was born!"); return new Horse(); } public Plant newPlant() { System.out.println("Fruit grows!"); return new Fruitage(); } }
import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.File; /** * @author hz * @version 1.0 */ public class ReadXML2 { public static Object getObject() { try { DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("src/AbstractFactory/config.xml")); NodeList nl = doc.getElementsByTagName("className"); Node classNode = nl.item(0).getFirstChild(); String cName = "AbstractFactory." + classNode.getNodeValue(); System.out.println("New class name:" + cName); Class<?> c = Class.forName(cName); Object obj = c.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); return null; } } }
- Advantages and disadvantages
advantage:
① The multi-level products associated in the product family can be managed together within the class, instead of introducing multiple new classes for management.
② When a product family is required, the abstract factory can ensure that the client always uses only the product group of the same product.
③ Abstract factory enhances the scalability of the program. When adding a new product family, there is no need to modify the original code to meet the opening and closing principle.
Disadvantages:
When a new product needs to be added to the product family, all factory classes need to be modified. It increases the abstraction and understanding difficulty of the system.
Reference articles
1,https://segmentfault.com/a/1190000040289636
2,https://segmentfault.com/a/1190000040297407
3,https://segmentfault.com/a/1190000040319351