Design pattern -- create pattern

Create mode

1, Singleton, singleton mode: ensure that a class has only one instance and provide a global access point to access it
2, Abstract Factory: provides an interface to create a series of related or interdependent objects without specifying their specific classes.  
3, Factory Method: define an interface for creating objects, and let subclasses decide which class to instantiate. Factory Method delays the instantiation of a class to subclasses.  
4, Builder, construction mode: separate the construction of a complex object from its representation, so that the same construction process can create different representations.  
5, Prototype: specify the type of objects to be created with prototype instances, and create new objects by copying these prototypes.

Structural mode

6, Iterator, iterator pattern: provides a method to sequentially access the elements of an aggregate object without exposing the internal representation of the object.  
7, Observer mode: defines one to many dependencies between objects. When the state of an object changes, all objects that depend on it are notified and automatically updated.  
8, Template Method: defines the skeleton of an algorithm in operation and delays some steps to subclasses. Template Method enables subclasses to redefine some specific steps of the algorithm without changing the structure of an algorithm.  
9, Command mode: encapsulate a request into an object, so that you can parameterize customers with different requests, queue and log requests, and support revocable operations.  
10, State mode: allows an object to change its behavior when its internal state changes. The object seems to have changed its class.  
11, Strategy: define a series of algorithms, encapsulate them one by one, and make them replace each other. This mode makes the algorithms independent of the customers who use them.  
12, China of Responsibility, responsibility chain mode: multiple objects have the opportunity to process the request, so as to avoid the coupling relationship between the sender and receiver of the request
13, Mediator, mediator mode: encapsulate the interaction of some columns of objects with a mediation object.  
14, Visitor: refers to an operation that acts on each element in an object structure. It enables you to define a new operation that acts on this element without changing the element class.  
15, Interpreter mode: given a language, define a representation of its grammar and define an interpreter that uses the representation to interpret sentences in the language.  
16, Memo mode: capture the internal state of an object without destroying the object, and save the state outside the object.  

Behavior pattern

17, Composite, composition mode: combine objects into a tree structure to represent the relationship between parts and the whole. Composite makes users use single objects and combined objects consistently.  
18, Facade, appearance mode: provide a consistent interface for a group of interfaces in the subsystem, fa?ade provides a high-level interface, which makes the subsystem easier to use.  
19, Proxy, proxy mode: provides a proxy for other objects to control access to this object
20, Adapter, adapter mode: convert an interface of one class into another interface desired by the customer. The adapter mode enables those classes that cannot work together due to incompatible interfaces to work together.  
21, Decorator, decoration mode: dynamically add some additional responsibilities to an object. In terms of added functions, decorator mode is more flexible than generating subclasses.  
22, Bridge, bridge pattern: separate the abstract part from its implementation part, so that they can change independently.  
23, Flyweight, enjoy yuan mode

Prototype

brief introduction
Specify the type of object to be created with the prototype instance, and create a new object by copying the prototype.

// Traps in development
public class Demo1 {
//    public static void main(String[] args) {
//        HashMap hm1 = new HashMap();
//        hm1.put("name","zs");
//        hm1.put("sex", "female");
//        HashMap hm2 = hm1;
//        hm1.put("age","18");
//        hm2.put("like", "male");
//        System.out.println(hm1);
//        System.out.println(hm2);
//    }
 
    public static void main(String[] args) {
        HashMap hm1 = new HashMap();
        hm1.put("name","zs");
        hm1.put("sex","female");
        HashMap hm2 = (HashMap) hm1.clone();
        hm1.put("age","18");
        hm2.put("like","male");
        System.out.println(hm1);
        System.out.println(hm2);
    }
}

term

prototype: prototype

clone: clone

case
Demand: Clone 10 copies of a sheep named Jack and female;

It is required that the attributes and gender of each sheep are consistent;

 - Before use
 
public class Sheep {
      private String name;
      private String sex;
  
      public Sheep(String name, String sex) {
          this.name = name;
          this.sex = sex;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public String getSex() {
          return sex;
      }
  
      public void setSex(String sex) {
          this.sex = sex;
      }
  
      @Override
      public String toString() {
          return "Sheep{" +
                  "name='" + name + '\'' +
                  ", sex='" + sex + '\'' +
                  '}';
      }
  }
 
  /*
   * Clone 10 copies of a sheep named Jack and female;
   * ​    It is required that the attributes and gender of each sheep are consistent;
   *
   * Disadvantages: the current state cannot be copied
   */
  public class Client {
      public static void main(String[] args) {
          Sheep sheep1 = new Sheep("Jesse", "mother");
          Sheep sheep2 = new Sheep("Jesse", "mother");
          Sheep sheep3 = new Sheep("Jesse", "mother");
          Sheep sheep4 = new Sheep("Jesse", "mother");
          Sheep sheep5 = new Sheep("Jesse", "mother");
          Sheep sheep6 = new Sheep("Jesse", "mother");
          Sheep sheep7 = new Sheep("Jesse", "mother");
          Sheep sheep8 = new Sheep("Jesse", "mother");
          Sheep sheep9 = new Sheep("Jesse", "mother");
          Sheep sheep10 = new Sheep("Jesse", "mother");
  
  // At this time, I want a sheep named Jerry, and other sheep have the same attributes as Jesse;
  // Then according to this design, you can only create the required sheep
  // At present, there are only two attributes created in this way, which is not a big problem. If sheep have more than ten or twenty attributes, then right and wrong
  // Often inconvenient
          Sheep sheep11 = new Sheep("Jerry", "mother");
  
      }
  }
 
 
--After use
 
/*
 * 
 * Design using prototype design pattern
 */
public class Sheep implements Cloneable{
    private String name;
    private String sex;
 
    public Sheep(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getSex() {
        return sex;
    }
 
    public void setSex(String sex) {
        this.sex = sex;
    }
 
    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj =  super.clone();
        System.out.println("Cloned...");
        return obj;
    }
}
 
 
package com.tangyue.design.prototype.after;
 
/**
 * Clone 10 copies of a sheep named Jack and female;
 * ​    It is required that the attributes and gender of each sheep are consistent;
 *
 *   The prototype design pattern is used for post design testing
 */
public class Client {
    public static void main(String[] args) throws Exception{
        Sheep sheep1 = new Sheep("Jesse", "mother");
        Sheep sheep2 = (Sheep) sheep1.clone();
        Sheep sheep3 = (Sheep) sheep1.clone();
        Sheep sheep4 = (Sheep) sheep1.clone();
        Sheep sheep5 = (Sheep) sheep1.clone();
        Sheep sheep6 = (Sheep) sheep1.clone();
        Sheep sheep7 = (Sheep) sheep1.clone();
        Sheep sheep8 = (Sheep) sheep1.clone();
        Sheep sheep9 = (Sheep) sheep1.clone();
        Sheep sheep10 = (Sheep) sheep1.clone();
        System.out.println(sheep1);
        System.out.println(sheep2);
 
// At this time, I want a sheep named Jerry, and other sheep have the same attributes as Jesse;
// According to the prototype design mode, the caller Client class does not need to find the attributes of the same part of Jesse, but only needs to change the attributes of the different part to clone;
// At present, there are only two attributes in this design. It doesn't make much difference when used. If sheep have more than ten or twenty attributes, it's very obvious
        sheep1.setName("Jerry");//Other properties do not need to be concerned
        Sheep sheep11 = (Sheep) sheep1.clone();
        System.out.println(sheep11);
    }
}

Conclusion: from the perspective of object creation, prototype pattern design makes the creation of similar class instances more convenient

Singleton mode

brief introduction
Ensure that a class has only one instance and provide a global access point to access it.

Singleton design pattern came into being. It is to solve the problem of resource waste caused by object initialization;  

breakthrough point
1. Why is spring's default javabean singleton?
2. Why does spring provide the javabean multi instance option?

-Classification
- Hungry Han formula (static constant)
- Hungry Chinese (static code block)
- lazy (thread unsafe)
- lazy (thread safe, synchronized code blocks)
- lazy (thread safe, synchronous method)
- double check
- static inner class
- Enumeration

/**
 * Hungry Han formula (static constant)
 */
public class DBAccess {
    // The constructor is privatized to avoid external object creation
    private DBAccess() {
 
    }
 
    // Static modification to ensure that it can be accessed by static methods
    private final static DBAccess dbAccess = new DBAccess();
 
    // External direct call static method instantiation object
    public static DBAccess getInstance() {
        return dbAccess;
    }
 
}
 
/**
 * Hungry Chinese style (static code block)
 */
class DBAccess2 {
    private DBAccess2() {
 
    }
 
    private static DBAccess2 dbAccess = null;
 
    static {
        dbAccess = new DBAccess2();
    }
 
    public static DBAccess2 getInstance() {
        return dbAccess;
    }
}
 
/**
 * Lazy (thread unsafe)
 */
class DBAccess3 {
    private DBAccess3() {
 
    }
 
    private static DBAccess3 dbAccess = null;
 
    public static DBAccess3 getInstance() {
        if (dbAccess == null) {
            dbAccess = new DBAccess3();
        }
        return dbAccess;
    }
}
 
/**
 * Lazy (synchronous code block)
 */
class DBAccess4 {
    private DBAccess4() {
 
    }
 
    private static DBAccess4 dbAccess = null;
 
    public static DBAccess4 getInstance() {
        synchronized (DBAccess4.class) {
            if (dbAccess == null) {
                dbAccess = new DBAccess4();
            }
        }
        return dbAccess;
    }
}
 
/**
 * Lazy (thread safety, synchronization method)
 */
class DBAccess5 {
    private DBAccess5() {
 
    }
 
    private static DBAccess5 dbAccess = null;
 
    public synchronized static DBAccess5 getInstance() {
        if (dbAccess == null) {
            dbAccess = new DBAccess5();
        }
        return dbAccess;
    }
}
 
/**
 * duplication check
 */
class DBAccess6 {
    private DBAccess6() {
 
    }
 
    private static DBAccess6 dbAccess = null;
 
    public static DBAccess6 getInstance() {
        if (dbAccess == null) {
            synchronized (DBAccess6.class) {
                if (dbAccess == null) {
                    dbAccess = new DBAccess6();
                }
            }
        }
        return dbAccess;
//        return new DBAccess6();
    }
}
 
/**
 * Static inner class
 */
class DBAccess7 {
    private DBAccess7() {
 
    }
 
    private static class DBAccess7Instance{
        private static DBAccess7 dbAccess = new DBAccess7();
    }
 
    public static DBAccess7 getInstance() {
        return DBAccess7Instance.dbAccess;
    }
}
 
/**
 * enumeration
 */
enum DBAccess8{
    DBACCESS;
    public static DBAccess8 getInstance() {
        return DBAccess8.DBACCESS;
    }
}


Conclusion:

In the single example, two hungry Chinese styles are available, but there are performance problems

In the single example, the three lazy types are not recommended. There is a thread safety problem. The synchronization method solves the thread problem, but the performance is very poor

The last three singleton modes are recommended

-Precautions
- there is only one object in this class in the system memory, which saves system resources. For some objects that need to be created and destroyed frequently, using singleton mode can improve the system performance
- when you want to instantiate a singleton class, you must remember to use the corresponding method to get the object instead of new
 

Demonstration, difference and selection of Spring single instance and multi instance mode

/**
 * Spring Demonstration, difference and selection of single case and multi case mode
 * 
 * @author Administrator
 *
 */
public class Demo1 {
    // scope="singleton" default
    @Test
    public void test1() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
        ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
        ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
        System.out.println(p1 == p2);
    }
 
    // scope="prototype"
    @Test
    public void test2() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
        ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
        ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
        System.out.println(p1 == p2);
    }
 
    // Difference: single case multiple case selection?
    @Test
    public void test3() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
        ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
        ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
        p1.execute();
        p2.execute();
    }
}


Factory mode (factory)

brief introduction

Factory mode is the most commonly used instantiation object mode. It is a mode that uses factory method instead of new operation. The famous Jive forum makes extensive use of factory mode, which can be seen everywhere in Java program system. Because factory mode is equivalent to creating new instance objects, we often need to generate instance objects according to Class. For example, a = new a() factory mode is also used to create instance objects, so we need to pay more attention to new in the future. Whether we can consider using factory mode. Although doing so may do more work, it will bring greater scalability and less modification to your system.
https://baike.baidu.com/item/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/9852061?fr=aladdin

breakthrough point

When does the javabean in Spring initialize, whether it is container initialization or factory created object initialization;

-Terminology

- Model
- Factory model Factory

Before use:

package com.tangyue.design.factory;
 

public interface Pizza {
    void pre();
 
    void bake();
 
    void cut();
 
    void box();
}
 
/**
 * Chinese pizza
 */
class ChinesePizza implements Pizza {
 
    public ChinesePizza() {
        this.pre();
        this.bake();
        this.cut();
        this.box();
    }
 
    @Override
    public void pre() {
        System.out.println("Preparation of Chinese pizza materials...");
    }
 
    @Override
    public void bake() {
        System.out.println("Chinese pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of Chinese pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("Chinese pizza packing box");
    }
}
 
/**
 * American pizza
 */
class AmericaPizza implements Pizza {
    public AmericaPizza() {
        this.pre();
        this.bake();
        this.cut();
        this.box();
    }
 
    @Override
    public void pre() {
        System.out.println("American pizza material preparation...");
    }
 
    @Override
    public void bake() {
        System.out.println("American pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of American pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("American pizza packing box");
    }
}
 
class JapanPizza implements Pizza {
    public JapanPizza() {
        this.pre();
        this.bake();
        this.cut();
        this.box();
    }
 
    @Override
    public void pre() {
        System.out.println("Preparation of Japanese pizza materials...");
    }
 
    @Override
    public void bake() {
        System.out.println("Japanese pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of Japanese pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("Japanese pizza packing box");
    }
}
 
 
public class PizzaFactory {
    public static Pizza createPizza(int no){
        switch (no){
            case 1:
                return new ChinesePizza();
            case 2:
                return new AmericaPizza();
            case 3:
                return new JapanPizza();
        }
        return null;
    }
}
 
 
public class Client {
    public static void main(String[] args) {
        Pizza chinaPizza = PizzaFactory.createPizza(1);
 
        System.out.println("=============================");
        Pizza americaPizza = PizzaFactory.createPizza(2);
 
        System.out.println("=============================");
        Pizza japanPizza = PizzaFactory.createPizza(3);
    }
}


After use:

package com.tangyue.design.factory.after;
 
public interface Pizza {
    void pre();
 
    void bake();
 
    void cut();
 
    void box();
}
 
/**
 * Chinese pizza
 */
class ChinesePizza implements Pizza {
 
    @Override
    public void pre() {
        System.out.println("Preparation of Chinese pizza materials...");
    }
 
    @Override
    public void bake() {
        System.out.println("Chinese pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of Chinese pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("Chinese pizza packing box");
    }
}
 
/**
 * American pizza
 */
class AmericaPizza implements Pizza {
 
    @Override
    public void pre() {
        System.out.println("American pizza material preparation...");
    }
 
    @Override
    public void bake() {
        System.out.println("American pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of American pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("American pizza packing box");
    }
}
 
class JapanPizza implements Pizza {
 
    @Override
    public void pre() {
        System.out.println("Preparation of Japanese pizza materials...");
    }
 
    @Override
    public void bake() {
        System.out.println("Japanese pizza baking...");
    }
 
    @Override
    public void cut() {
        System.out.println("Slicing of Japanese pizza...");
    }
 
    @Override
    public void box() {
        System.out.println("Japanese pizza packing box");
    }
}
 
 
 
public class PizzaFactory {
    public static Pizza createPizza(int no){
        Pizza pizza = null;
        switch (no){
            case 1:
                pizza = new ChinesePizza();
                break;
            case 2:
                pizza = new AmericaPizza();
                break;
            case 3:
                pizza = new JapanPizza();
                break;
        }
        if (pizza == null){
            System.out.println("This pizza ordering service is not available");
        }else {
            pizza.pre();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
        return pizza;
    }
}
 
 
public class Client {
    public static void main(String[] args) {
        Pizza chinaPizza = PizzaFactory.createPizza(1);
 
        System.out.println("=============================");
        Pizza americaPizza = PizzaFactory.createPizza(2);
 
        System.out.println("=============================");
        Pizza japanPizza = PizzaFactory.createPizza(3);
 
        System.out.println("=============================");
        Pizza otherPizza = PizzaFactory.createPizza(4);
    }
}


Comparison of codes before and after use:

The former gives the object initialization to the constructor of the object;

The latter gives the initialization process to the factory class;

The advantage of this is that it decouples its own object instantiation and object initialization actions. Another factor is that the initialization of constructor will affect subclasses;

-Precautions and details

Give the initialization of the object to the factory class
Constructor initialization will affect subclasses, and the coupling degree is too high

Abstract factory

Hibernate Framework
Spring framework
Mybatis framework
Shiro framework
 

**Bean Life cycle of (single case, multiple cases) bean Initialization source code analysis)**
 
/**
 * Bean Life cycle of
        Singleton object
            Birth: the object is born when the container is created
            Alive: the object is alive as long as the container is still there
            Death: the container is destroyed and the object dies
            Summary: the lifecycle of a singleton object is the same as that of a container
        Multiple objects
            Birth: when we use objects, the Spring framework creates them for us
            Alive: an object is alive as long as it is in use
            Death: when an object is not used for a long time and there is no other object reference, it is collected by the Java garbage collector
 * 
 * @author Administrator
 *
 */
public class Demo2 {
    
//The initialization time of a singleton object is different from that of a multi instance object, which is demonstrated by the scope attribute
    @Test
    public void test1() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    }
    
//The initialization time of a singleton object is different from that of a multi instance object, which is demonstrated by the scope attribute
    @Test
    public void test2() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
        InstanceFactory i1 = (InstanceFactory) applicationContext.getBean("instanceFactory");
        i1.service();
//scope="prototype", closing the container will not automatically destroy the bean object
        applicationContext.close();
    }
    
    /**
     * Two points are explained:
     * scope The value of corresponds to two factory classes, and the mode of producing JavaBeans is the same;
     * 1.One is a single case and the other is multiple cases
     * 2.One is immediate initialization and the other is using initialization
     * Anyway, we need to initialize once. Just put all the initialization operations into the listener to improve the performance of the system application
     * Multiple instances themselves will consume performance, so try to create objects when using them
     */
    @Test
    public void test3() {
//        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
        
        Resource resource = new ClassPathResource("/spring-context.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource );
        InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
    }
}
 

**other**

package com.zking.single.demo;
 
public class InstanceFactory {
    public void init() {
        System.out.println("Initialization method");
    }
    
    public void destroy() {
        System.out.println("Destruction method");
    }
    
    public void service() {
        System.out.println("Business method");
    }
}
 
<bean id="instanceFactory" class="com.zking.single.demo.InstanceFactory"
        scope="prototype" init-method="init" destroy-method="destroy"></bean>

Tags: Singleton pattern

Posted by shivers on Tue, 19 Apr 2022 00:52:09 +0930