On design mode

(1) Singleton mode
The singleton pattern contains only a special class called singleton in its core structure. The singleton pattern ensures that there is only one instance of a class in the system.

characteristic:
1. A singleton class can only have one instance.
2. A singleton class must create its own unique instance.
3. A singleton class must provide this instance to all other objects

Key points of singleton mode:
1. Private construction method
2. Private static reference to own instance
3. A static public method with its own instance as the return value

The singleton mode can be divided into two types according to the timing of instantiating objects:
One is the hungry man type single case, the other is the lazy man type single case.

Hungry Chinese singleton instantiates an object and gives it a reference when the singleton class is loaded; The lazy type instantiates the object only when calling the get instance method.

The code is as follows:

Hungry Han style single example:
public class Singleton {

private static Singleton singleton = new Singleton(); 

private Singleton(){} 

public static Singleton getInstance(){     
    return singleton;   
} 

}

Lazy single example:

public class Singleton {   
    private static Singleton singleton; 

  private Singleton(){} 

  public static synchronized Singleton getInstance(){     
      if(singleton==null){       
          singleton = new Singleton();     
      }     
      return singleton;   
  } 
} 


There is another common form of singleton mode: the form of double lock

public class Singleton{  
  private static volatile Singleton instance=null;  
  
  private Singleton(){    
    //do something  
  }  
  
  public static Singleton getInstance(){    
      if(instance==null){      
          synchronized(SingletonClass.class){        
              if(instance==null){          
                  instance=new Singleton();        
              }      
          }    
       }    
       return instance;  
   }
}


This mode will synchronize the content below to if Internally, it improves the efficiency of execution. It is not necessary to synchronize every time the object is obtained. It is synchronized only for the first time. It is not necessary after it is created.
In this mode, the efficiency of double judgment and synchronization is much higher than that in the above example, because if the single layer if Judge that if the server allows, suppose there are 100 threads, and the time spent is 100*(Synchronization judgment time+if Judgment time), and if double if It is judged that 100 threads can be used at the same time if Judging, the theory consumes only one time if The time of judgment.

Therefore, in the case of high concurrency and lazy mode, the best choice is double judgment and synchronization.

Advantages of singleton mode:

1,There is only one object in memory to save memory space.
2,Avoiding frequent creation and destruction of objects can improve performance.
3,Avoid multiple occupation of shared resources.
4,Can be accessed globally.

Disadvantages of singleton mode:

1,Expansion difficulties due to getInstance Static functions cannot generate instances of subclasses. If you want to expand, you have to rewrite that class.
2,Implicit use causes unclear class structure.
3,Problems that may cause program memory leaks.

Applicable scenarios:

Because of the above advantages of singleton mode, it is a design mode used more in programming. The following is a scenario using singleton mode:
1,Objects that need to be instantiated frequently and then destroyed.
2,Objects that take too much time or resources to create, but are often used.
3,In the case of resource sharing, avoid performance or loss caused by resource operation
4,In the case of controlling resources, it is convenient for resources to communicate with each other.

Precautions for singleton mode:

1.You can only use the methods provided by the singleton class to get the singleton object. Do not use reflection, otherwise a new object will be instantiated.
2.Do not do the dangerous operation of disconnecting singleton class objects from static references in classes.
3.Pay attention to thread safety when using shared resources by multithreading singleton.

Some common questions about singleton pattern in Java:

I Will singleton mode objects be collected by the jvm garbage collector if they are not used for a long time?
The jvm garbage collector will not recycle singleton objects unless the singleton static reference is disconnected from the singleton object artificially.
The judgment conditions of JVM unloading class are as follows:
1. All instances of this class have been recycled, that is, there are no instances of this class in the java heap.
2. The ClassLoader that loads this class has been recycled.
3. The corresponding Java Lang. class objects are not referenced anywhere, and methods of this class cannot be accessed anywhere through reflection.
Only when all three conditions are met will the jvm unload the class during garbage collection. Obviously, the singleton class does not meet condition 1, so the singleton class will not be recycled.

II Will there be multiple singletons in a jvm?
In the case of distributed systems, multiple class loaders, and serialization, multiple singletons will be generated. Will singletons be generated in the same jvm? Using the getInstance() method provided by the singleton can only get the same singleton. Unless the reflection method is used, a new singleton will be obtained.
The code is as follows:

Class c = Class.forName(Singleton.class.getName()); 

Constructor ct = c.getDeclaredConstructor(); 

ct.setAccessible(true); 

Singleton singleton = (Singleton)ct.newInstance();

In this way, each run will produce a new singleton object. Therefore, when using singleton mode, be careful not to use reflection to generate new singleton objects.

III Is there an advantage of synchronization on the getInstance() method, or is it better to synchronize only the necessary blocks?

Because locking only makes sense when an instance is created, and then other times the instance is only read-only, it is better to synchronize only the necessary blocks and is a better choice.
Disadvantages: only in the first call can two objects be generated, and synchronization must be required. And once singleton Not for null,The system still costs synchronization lock overhead, which is a little more than worth the loss.

IV Can singleton classes be inherited
According to the timing and mode of single instance construction, single instance mode can also be divided into several types. However, inheritance is not supported for singleton classes that provide instances through privatized constructors and static methods.
The singleton implementation of this pattern requires each specific singleton class to maintain singleton instances and limit the generation of multiple instances. However, another idea of realizing singleton can be adopted: registered singleton to make singleton open to inheritance. Implementation principle of typical column sub Spring IOC.

(2) Factory mode
This type of design pattern is a creation pattern, which provides the best way to create objects.
Factory mode mainly provides a transition interface for creating objects, so as to shield and isolate the specific process of creating objects, so as to improve flexibility.

The factory pattern is divided into three types according to the degree of abstraction:
1. Simple factory mode (also known as static factory mode)
2. Factory method model (also known as polymorphic factory)
3. Abstract factory pattern (also called toolbox)

Simple factory mode:
In essence, a factory class dynamically determines which instance of a product class (which inherits from a parent class or interface) should be created according to the passed parameters. For the creation target of the simple factory pattern, all the created objects are instances of a specific class acting as this role.

Factory method mode:
Factory method is a design pattern with small granularity, because the representation of pattern is only an abstract method. Define the interface for creating objects in advance, and let the subclass decide to instantiate a specific class, that is, add an interface between the factory and the product. The factory is no longer responsible for the creation of the product. The interface returns specific class instances according to different conditions, which are implemented by specific class instances.

Abstract factory pattern:
A factory pattern used when there are multiple Abstract roles. The abstract factory pattern can provide an interface for the client to create multiple product objects without specifying the specific product. It has multiple abstract product classes. Each abstract product class can derive multiple specific product classes. An abstract factory class can derive multiple specific factory classes. Each specific factory class can create multiple instances of specific product classes.

Factory method mode should be used more in practice. We take factory method mode as an example

Abstract product class: define car vehicle class

public interface Car {  
     void gotowork();
}

Define the actual product classes. There are two in total. bike and bus represent different vehicle classes respectively

public class Bike implements Car {  
    @Override  
    public void goToWork() {    
        System.out.println("Go to work by bike!");  
    } 
}

public class Bus implements Car {  
    @Override  
    public void goToWork() {    
        System.out.println("Go to work by bus!");  
    } 
}

Define abstract factory interfaces

public interface ICarFactory {  
    Car getCar(); 
}

Specific factory subclasses. Create different factory subclasses for each specific product class

public class BikeFactory implements ICarFactory {  
    @Override  
    public Car getCar() {    
        return new Bike();  
    } 
}

public class BusFactory implements ICarFactory {  
    @Override  
    public Car getCar() {    
        return new Bus();  
    } 
}

Simple test classes to verify that different factories can produce different product objects

public class TestFactory {  
    @Test  
    public void test() {    
        ICarFactory factory = null;    
        // bike    
        factory = new BikeFactory();    
        Car bike = factory.getCar();    
        bike.goToW    ork(); //Go to work by bike!   
        // bus    
        factory = new BusFactory();    
        Car bus = factory.getCar();    
        bus. goToWork();   //Go to work by bus!  
    } 
}


Advantages of factory mode:

    1,If a caller wants to create an object, he just needs to know its name, which reduces the degree of coupling.
    2,High scalability. If you want to add a product, you can only extend a factory class. Make the code structure clearer.
    3,Mask the specific implementation of the product, and the caller only cares about the product interface.

Disadvantages of factory mode:

    Each time you add a product, you need to add a specific class and object implementation factory, so that the number of classes in the system increases exponentially, which not only increases the complexity of the system to a certain extent, but also increases the dependence of the specific classes of the system. Therefore, for simple objects, using factory pattern increases complexity.

Applicable scenarios of factory mode:

    1, An object has many subclasses.
    2, Creating an object requires many additional operations.
    3, The system needs to be extended frequently in the later stage. It assigns the task of object instantiation to the implementation class, which has good expansibility.

Some frequently asked questions about factory patterns in Java:

    1.Using the downward transformation of the parent class (using the reference of the parent type to point to the object of the child class) can achieve the effect similar to the factory mode, so why use the factory mode?
   Assigning a parent reference to a subclass object to a subclass reference is called a downward transformation, such as: 

Class Student extends Person 

Person s = new Student();  
Student a = (Student)s;

When using downward transformation to instantiate a subclass on the client side, it heavily depends on the name of the specific subclass. When we need to change the construction method of subclasses, such as adding a parameter or changing the class name of subclasses, all new subclasses need to be changed.
However, if we use the factory mode, we only need to modify the code of new in the factory, and the code used in this instance in other projects will be changed accordingly without manual operation.

Summary:
Whether it is simple factory pattern, factory method pattern or abstract factory pattern, they essentially extract the unchanged parts and leave the variable parts as interfaces to achieve maximum reuse.

(3) Template method pattern
Define the framework of an algorithm in operation, and delay some steps to subclasses, so that subclasses can redefine some specific steps in the algorithm without changing the structure of the algorithm.

Type: behavior class pattern

Class diagram:

In fact, the template method is A frequently used pattern in programming. Let's take A look at an example. One day, programmer A got A task: given an integer array, sort the numbers in the array from small to large, and then print the sorted results. After analysis, this task can be divided into two parts: sorting and printing. The printing function is easy to realize, and sorting is A little troublesome. But A has A way. First, complete the printing function and find someone else to do the sorting function.

abstract class AbstractSort {  

  /** 
  * Sort the array array from small to large 
  * @param array 
  */  
  protected abstract void sort(int[] array); 

  public void showSortResult(int[] array){ 
    this.sort(array); 
    System.out.print("Sorting results:"); 
    for (int i = 0; i < array.length; i++){ 
      System.out.printf("%3s", array[i]); 
    } 
  } 
}


After writing, A found his colleague B and said: there is A task. I have written the main logic. You can implement the rest of the logic. So give the AbstractSort class to B and let B write the implementation. B take it and have A look. It's too simple. It'll be done in 10 minutes. The code is as follows:

class ConcreteSort extends AbstractSort {  

    @Override 
    protected void sort(int[] array){ 
      for(int i=0; i<array.length-1; i++){ 
        selectSort(array, i); 
      } 
    } 

    private void selectSort(int[] array, int index) { 
      int MinValue = 32767; // Minimum variable 
      int indexMin = 0; // Minimum index variable 
      int Temp; // Temporary variable 
      for (int i = index; i < array.length; i++) { 
        if (array[i] < MinValue){ // Minimum value found 
          MinValue = array[i]; // Store minimum 
          indexMin = i;  
        } 
      } 
      Temp = array[index]; // Exchange two values 
      array[index] = array[indexMin]; 
      array[indexMin] = Temp; 
    } 
  }


Write it and give it to A. A brings it for operation:

public class Client {  
  public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 }; 
  // Preset data array 
  public static void main(String[] args){ 
    AbstractSort s = new ConcreteSort(); 
    s.showSortResult(a); 
  } 
}

Operation results:
Sorting result: 0 1 3 4 5 7 9 10 12 32
Normal operation. All right, the task is complete. This is the template method pattern.

Structure of template method pattern
The template method pattern consists of an abstract class and an (or a group) implementation class through an inheritance structure
There are three methods in abstract classes:
1. Abstract method: the parent class only declares but does not implement it. Instead, the specification is defined and then implemented by its subclasses.
2. Template method: it is declared and implemented by abstract classes. Generally speaking, template methods call abstract methods to complete the main logical functions, and most template methods are defined as final type, indicating that the main logical functions cannot be overridden in subclasses.
3. Hook method: declared and implemented by abstract class. However, subclasses can be extended, and subclasses can affect the logic of template methods by extending hook methods.

Implementation classes are used to implement details. The template method in the abstract class completes the business logic by implementing the method of class extension. As long as the extension method in the implementation class passes the unit test, on the premise that the template method is correct, the overall function generally will not have major errors.

Advantages and applicable scenarios of template method

    Easy to expand. Generally speaking, the template method in the abstract class is the part that is not easy to generate and change, and the abstract method is the part that is easy to generate and change. Therefore, it is generally easy to expand the function by adding the implementation class, which conforms to the opening and closing principle.
  Easy to maintain. For the template method mode, it is precisely because their main logic is the same that the template method is used. If the template method is not used, it is very inconvenient to allow these same codes to be scattered in different classes.
  Quite flexible. Because there are hook methods, the implementation of subclasses can also affect the operation of the main logic in the parent class. However, while being flexible, the subclass affects the parent class, violates the Richter substitution principle, and will also bring risks to the program. This has higher requirements for the design of abstract classes.
  When multiple subclasses have the same methods and the logic of these methods is the same, you can consider using the template method pattern. When the main framework of the program is the same and the details are different, it is also more suitable to use this mode.

(4) Strategy mode
Define a set of algorithms, encapsulate each algorithm, and make them interchangeable.
Type: behavior class pattern
Class diagram:

    Policy pattern is the encapsulation of algorithms, which encapsulates a series of algorithms into corresponding classes, and these classes implement the same interface and can be replaced with each other. In the template method pattern mentioned earlier, we also focus on the encapsulation of algorithms.
    As can be seen from the class diagram, the difference between the policy pattern and the template method pattern is only that there is a separate encapsulation class Context,The difference between the template method and the template method is that in the template method mode, the main body of the algorithm is called in the abstract parent class, while in the policy mode, the main body of the calling algorithm is encapsulated to the encapsulation class. Context Abstract strategy Strategy It is generally an interface for the purpose of defining specifications, which generally does not contain logic.
    In fact, this is only a general implementation. In actual programming, because there is inevitably some same logic between various specific strategy implementation classes, we often use abstract classes to avoid repeated code Strategy The role of encapsulates public code. Therefore, in many application scenarios, the shadow of the template method pattern is generally seen in the policy pattern.

Structure of policy pattern
1. Encapsulation class: also known as context, it encapsulates the policy twice to avoid the direct call of the high-level module to the policy.
2. Abstract strategy: generally, it is an interface. When there is duplicate logic in each implementation class, the image class is used to encapsulate this part of public code. At this time, the policy pattern looks more like the template method pattern.
3. Specific policy: the specific policy role is usually assumed by a group of classes that encapsulate the algorithm, and these classes can be freely replaced as needed.

Policy pattern code implementation

interface IStrategy { 
    public void doSomething(); 
}


class ConcreteStrategy1 implements IStrategy { 

    public void doSomething() { 
      System.out.println("Specific strategy 1"); 
    } 
} 
class ConcreteStrategy2 implements IStrategy { 

    public void doSomething() { 
      System.out.println("Specific strategy 2"); 
    } 
} 

class Context { 
    private IStrategy strategy; 

    public Context(IStrategy strategy){ 
      this.strategy = strategy; 
    } 

    public void execute(){ 
      strategy.doSomething(); 
    } 
 } 

 public class Client { 
    public static void main(String[] args){ 
      Context context; 
      System.out.println("-----Execute strategy 1-----"); 
      context = new Context(new ConcreteStrategy1()); 
      context.execute(); 

      System.out.println("-----Execution strategy 2-----"); 
      context = new Context(new ConcreteStrategy2()); 
      context.execute(); 
    } 
 }


Advantages and disadvantages of policy mode
The main advantages of the strategy mode are:
(1) Policy classes can switch freely. Since policy classes are implemented from the same abstraction, they can switch freely.
(2) It is easy to expand. Adding a new policy is very easy for the policy mode. Basically, it can be extended without changing the original code.
(3) Avoid using multiple conditions. If you do not use the policy mode, you must use conditional statements to connect all algorithms, and determine which algorithm to use through conditional judgment. As we mentioned in the previous article, using multiple conditional judgment is very difficult to maintain.

There are two main disadvantages of the policy mode:
(1) Maintaining various policy classes will bring additional expenses to development. Maybe everyone has experience in this aspect: Generally speaking, it is a headache if the number of policy classes exceeds 5.
(2) The client must be (caller) exposes all policy classes, because which policy to use is determined by the client. Therefore, the client should know what policies there are and understand the differences between various policies. Otherwise, the consequences will be serious. For example, there is a policy model of sorting algorithm, which provides three algorithms: quick sorting, bubble sorting and selective sorting, which are used by the client Before these algorithms, do you need to understand the application of these three algorithms? For another example, the client should use a container, which is implemented by linked list and array. Should the client also understand the difference between linked list and array?

Applicable scenarios:

   For object-oriented design, you must be familiar with the strategy pattern, because it is essentially inheritance and polymorphism in object-oriented. After reading the general code of the strategy pattern, I think that even if you have never heard of the strategy pattern before, you must have used it in the development process? You can consider using the policy mode in at least the following two cases:

(1) The main logic of several classes is the same, and there are only slight differences in the algorithm and behavior of some logic.
(2) If there are several similar behaviors, or algorithms, and the client needs to dynamically decide which one to use, the policy pattern can be used to encapsulate these algorithms for the client to call.

Policy mode is a simple and commonly used mode. We often use it intentionally or unintentionally during development. Generally speaking, policy mode will not be used alone. It is often mixed with template method mode and factory mode.

Keywords: Java Back-end

Added by Punk Rock Geek on Wed, 22 Dec 2021 08:13:32 +0200