java -- Design Pattern -- singleton and factory

Keywords: Java Singleton pattern

Design pattern

Concept: a pattern is a summary of code design experience that is repeatedly used, known by most people, written by classification; It is not a syntax specification, but a set of solutions to improve code reusability, maintainability, readability, robustness and security.

Tip: the following is the main content of this article. The following cases can be used for reference

1, Design pattern

Summary of good code experience

effect

  1. Improve programmer ability
  2. Improve the efficiency of program standardization and shorten the development cycle
  3. It makes the code reusable, readable, reliable, flexible and maintainable

category

23 species in three categories

  1. Creative pattern: factory method pattern, abstract factory pattern, singleton pattern, builder pattern, prototype pattern.
  2. Structural mode: adapter mode, decorator mode, agent mode, appearance mode, bridge mode, combination mode, sharing mode.
  3. Behavioral mode: policy mode, template method mode, observer mode, iteration sub mode, responsibility chain mode, command mode, memo mode, state mode, visitor mode, mediator mode and interpreter mode.

Principles followed by design patterns

  1. Open Close Principle

    It is open to extensions and closed to modifications
    When upgrading and maintaining the program in use, the original code of the software needs to be modified. Errors may be introduced into the previous code, and we may have to reconstruct the whole function, and the original code needs to be retested.
    Solution: when the software needs to change, try to realize the change by expanding the behavior of the software entity, rather than by modifying the existing code.

  2. Liskov Substitution Principle

    The principle of replacing the parent with a subclass can expand the function of the parent without changing the function of the parent
    If there is an object o2 of type T for each object o1 of type S, so that the behavior of all programs P defined by t does not change when all objects o1 replace o2, then type S is a subtype of type T.

  3. Dependency Inversion Principle

This is the basis of the opening and closing principle. Interface programming depends on abstraction rather than concrete. High level modules should not rely on low-level modules. Both should rely on their abstraction. Abstraction should not rely on details. Details should rely on abstraction

  1. Interface aggregation principle

    Use multiple isolated interfaces to reduce chelation
    Problem: Class A depends on class B through interface I, and class C depends on class D through interface I. If interface I is not the minimum interface for class A and class B, class B and class D must implement methods they do not need.
    Solution: split the bloated interface I into several independent interfaces. Class A and class C establish dependencies with the interfaces they need respectively. That is, the principle of interface isolation is adopted.

  2. Demeter Principle
    Don't talk to strangers.
    An entity should interact with other entities as little as possible to make the functional modules of the system relatively independent
    Problem: the closer the relationship between classes, the greater the degree of coupling. When one class changes, the greater the impact on another class.
    Solution: minimize the coupling between classes.

  3. Composite Reuse Principle

The principle is to try to use composition / aggregation instead of inheritance. Inheritance actually destroys the encapsulation of classes, and the methods of superclasses may be modified by subclasses.
Problem: if class B inherits class A, the implementation details of class A's inheritable method m are exposed to class B. If method m of class a changes, the implementation of B has to change

Aggregation: the object of B is destroyed and has no effect on the object of A

Composition: the object of B is destroyed, and the object of A does not exist
7. Single responsibility principle

A class is responsible for the response responsibilities of only one functional domain.

If a class assumes too many responsibilities, it is equivalent to coupling these responsibilities. The change of one responsibility may weaken or inhibit the ability of the class to complete other responsibilities. In addition, the coupling of multiple responsibilities will affect reusability.

Problem: for example, a class T is responsible for two different responsibilities: responsibility P1 and responsibility P2. When class T needs to be modified due to the change of responsibility P1 requirements, the function of responsibility P2 that originally runs normally may fail.

Solution: follow the principle of single responsibility. Two classes T1 and T2 are established respectively to enable T1 to complete the function of responsibility P1 and T2 to complete the function of responsibility P2. In this way, when modifying class T1, there is no risk of failure of responsibility P2; Similarly, when T2 is modified, there is no risk of failure of responsibility P1.

2, Common design patterns

1. Factory Method

General concept:
Factory pattern is a creative design pattern, which provides the best way to create objects. Hide the complex logical processing process and only care about the execution results. It can be done directly with new without using factory mode. It is used where complex objects need to be generated

1.1. Simple factory mode static factory mode

1.1.1. Concept

In the simple factory mode, you can return instances of different classes according to different parameters. The simple factory pattern specifically defines a class to be responsible for creating instances of other classes

1.1.2. Advantages

Powerful, creating objects and using objects are separated. Programmers only care about the use of objects, not how to create objects

1.1.3. Disadvantages

The coupling degree is high (all products are in the factory, but once abnormal, all products in the factory will be affected), and the expansibility is not strong (it will change every time the factory class is added), which violates the opening and closing principle

1.1.4. Examples

The code is as follows (example):
Interface

 package org.example.dp.factory2.simple;
//Software technology
public interface SoftwareTechnology
{
    void studyST();
}

Implementation class

/**
 * @author zhangyifan
 * @version 8.0
 * @description:java technology
 * @date 2021/12/2 14:30
 */
public class javaDevTechnology implements SoftwareTechnology{
    @Override
    public void studyST() {
        System.out.println("study java technology");
    }
}
/**
 * @author zhangyifan
 * @version 8.0
 * @description: Python Software technology
 * @date 2021/12/2 14:31
 */
public class PythonDevTechnology implements SoftwareTechnology {
    @Override
    public void studyST() {
        System.out.println("study python technology");
    }
}

factory

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 14:34
 */
public class AAAFactory {
    //method
    public SoftwareTechnology teschST(int type){
        if (type==1){
            return new PythonDevTechnology();
        }else if (type==2){
            return new javaDevTechnology();
        }else {
            return null;
        }
    }
}

Test class

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 14:34
 */
public class Test {
    public static void main(String[] args) {
        AAAFactory aaaFactory=new AAAFactory();
        SoftwareTechnology softwareTechnology = aaaFactory.teschST(1);
        if (softwareTechnology!=null){
            softwareTechnology.studyST();
        }else {
            System.out.println("Without this technology");
        }
    }
    /*Learning python Technology*/
}

1.2 factory (method) mode

1.2.1 concept

The factory method pattern defines an interface for creating objects and lets subclasses decide which class to instantiate. The factory method delays the instantiation of a class to a subclass.

The factory itself does not create products, but specifies the specifications to the factory, that is, the factory interface, and assigns the creation of products to the sub factory

1.2.2 advantages

The opening and closing principle is followed (products can be added without modifying the factory class)
Decoupling and single responsibility (each factory is only responsible for the corresponding products)

1.2.3 disadvantages

Increase system complexity (each product needs a new factory)

example

The code is as follows (example):
Factory specification

public interface AAAStanderFactory {
    /* Formulate interface standards before standardizing the use of factory interfaces*/
    SoftwareTechnology teachST();
}

Product realization sub factory class

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 14:51
 */
public class BejingAAAFactory implements AAAStanderFactory{
    /*   The opening and closing principle is followed (products can be added without modifying the factory class)*/
    /*    Decoupling and single responsibility (each factory is only responsible for creating corresponding products)*/
    @Override/* Increase system complexity (each new product needs to add a new factory)*/
    public SoftwareTechnology teachST() {
        return new javaDevTechnology();
    } 
}
/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 14:55
 */
public class WuHanAAAFactory implements AAAStanderFactory{
    @Override/**/
    public SoftwareTechnology teachST() {
        return new PythonDevTechnology();
    }
}


Test class

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 14:56
 */
public class TEst {
    public static void main(String[] args) {
        AAAStanderFactory aaaStanderFactory=new BejingAAAFactory();
        aaaStanderFactory.teachST().studyST();
        AAAStanderFactory aaaStanderFactory1=new WuHanAAAFactory();
        aaaStanderFactory1.teachST().studyST();
    }
}

result
Learning java technology
Learning python Technology

1.3 Abstract Factory

1.3.1 concept

Abstract factory is an upgraded version of factory methods. It provides an interface for related or interdependent objects without specifying specific implementation classes

The factory pattern of abstract class is for multiple product families. The factory method is a product family and a factory class. The second abstract factory is multiple product families and a factory class

1.3.2 advantages

When multiple objects in a product family are designed to work together, it can ensure that clients can always use only objects in the same 2 product family.

1.3.3 disadvantages

It is difficult to support new types of products. Because the abstract factory interface determines the collection of products that can be created. It is difficult to extend Abstract factories to produce new kinds of products.

The code is as follows (example):

Define interface

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 15:11
 */
public interface DiggerTechnology {
    void stuDT();
}

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 15:10
 */
public interface AAAStractFactory {
    /* Disadvantages: it is difficult to support new types of products. Because the abstract factory interface determines the set of products that can be created, it is difficult to extend the abstract factory to produce new kinds of products.*/
    /* Software technology*/
    SoftwareTechnology teachIT();
    /* Excavator Technology*/
    DiggerTechnology teachDT();
}

Realization factory

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 15:17
 *//* When multiple objects in a product family are designed to work together, it can ensure that clients always use only objects in the same product family*/
public class ShenZhenFactory implements AAAStractFactory{
    @Override
    public SoftwareTechnology teachIT() {
        return new PythonDevTechnology();/* python*/
    }

    @Override
    public DiggerTechnology teachDT() {
        return new GrabTechnology();/* Open excavator*/
    }
}


test

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 15:19
 */
public class Test {
    public static void main(String[] args) {
        AAAStractFactory aaaStractFactory=new ShenZhenFactory();
     /*   aaaStractFactory.teachDT().stuDT(); It's hard to tell
        aaaStractFactory.teachIT().studyST();*/
        System.out.println("========");
        DiggerTechnology diggerTechnology=aaaStractFactory.teachDT();
        diggerTechnology.stuDT();
        SoftwareTechnology softwareTechnology=aaaStractFactory.teachIT();
        softwareTechnology.studyST();
    }
}

2. Singleto mode

concept

A common software design pattern, the so-called single column, is that there is only one object in a class during project operation, that is, there are many places where this class is used, and there is only one object.

advantage

  1. Save memory
  2. In some cases, not using the singleton mode may cause code logic errors (for example, the website traffic statistics function ServletContext (serve) application (jsp) application. setAttbuter ("count", 100);

Attention

  1. Classes that are singleton mode only provide private constructors;
  2. Is a static private object of the class contained in the class definition;
  3. This class provides a static public function to create or obtain its own static private object

Several implementation methods (examples):
1. Lazy thread (unsafe)

/**
 * @author zhangyifan
 * @version 8.0
 * @description: Thread unsafe
 * @date 2021/12/2 16:01
 */
public class SlackerThreadUnsafe {
    //1 private construction methods prevent objects from being created elsewhere
   private   SlackerThreadUnsafe(){};
    //2. The static private class instance static is executed with the loading of the class, and the private class is executed only once to prevent the property from being accessed in other classes
    private static SlackerThreadUnsafe instance;
    //3 public static method that returns an instance of this class
    public static SlackerThreadUnsafe getInstance(){
        if (instance==null){
            instance=new SlackerThreadUnsafe();
        }
        return instance;
    }
}

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/12/2 16:13
 */
public class Test {
    public static void main(String[] args) {
        // new SlackerThreadUnsafe(); cannot new
        /*SlackerThreadUnsafe a=SlackerThreadUnsafe.*/
        SlackerThreadUnsafe ins1=SlackerThreadUnsafe.getInstance();
        SlackerThreadUnsafe ins2=SlackerThreadUnsafe.getInstance();
        SlackerThreadUnsafe ins3=SlackerThreadUnsafe.getInstance();
        //A common software design pattern. The so-called singleton is to make a class have only one object during project operation, that is, there are many places where this class is used, and there is only one object.
        System.out.println(ins1==ins2);//The ture object has always been a
        System.out.println(ins3==ins2);//ture
    }
}

2. Lazy line safety lock

/**
 * @author zhangyifan
 * @version 8.0
 * @description: Lock safe single thread
 * @date 2021/12/2 16:20
 */
public class SlackerTheadsafety {
    //1 private construction methods prevent objects from being created elsewhere
    private   SlackerTheadsafety(){};
    //2. The static private class instance static is executed with the loading of the class, and the private class is executed only once to prevent the property from being accessed in other classes
    private static SlackerTheadsafety instance;
    //3 public static method, which returns the instance of this class and locks the synchronized package to ensure thread safety
    public static synchronized SlackerTheadsafety getInstance(){
        if (instance==null){
            instance=new SlackerTheadsafety();
        }
        return instance;
    }
}

3. Lazy line safety double locking DCL lazy type

/**
 * @author zhangyifan
 * @version 8.0
 * @description: Dual thread lock is greatly safe
 * @date 2021/12/2 16:26
 */
public class SlackerThreadSafetyDoubleLock {
    private SlackerThreadSafetyDoubleLock(){};

    /***
      volatile
        1.Thread visible
        2.Prevent instruction rearrangement. In the case of multithreading, instruction replay may occur. singleton is null, that is, aaaa is null
     SlackerThreadSafetyDoubleLock    aaaa = new SlackerThreadSafetyDoubleLock();
        In the jvm 1. Create space in the heap (Eden Park)
                          2,Assign values to object properties
                        3,Point to the space with the aaaa reference
                        The execution sequence of the above three four atom operations may be 1.2.3 or 1.3.2.
                            Only the sequence of 1.2.3 can be executed normally
                        volatile The addition of keywords must be in the order of 1. 2.3

     */
    private volatile static SlackerThreadSafetyDoubleLock aaaa;
    //volatile keyword is used to prohibit instruction rearrangement and ensure return
    //volatile only guarantees visibility and order, not atomicity

    public   static  SlackerThreadSafetyDoubleLock getAaaa(){

        //If there is no object, create the object
        if (aaaa==null){
            //If n threads are judged to be empty, all n threads will enter the above judgment to prevent all three from instantiating objects
            synchronized (SlackerThreadSafetyDoubleLock.class){
                //After the first object is instantiated, prevent the rest from being instantiated. / / prevent one thread from executing and other threads from getting the lock and executing object creation again
                if (aaaa==null){
                    aaaa = new SlackerThreadSafetyDoubleLock();
                }
            }
        }
        return aaaa;
    }
    //Newly added
       public static void main(String[] args) throws Exception {
        //Use reflection to crack / / there is no absolute security
        SlackerThreadSafetyDoubleLock a2=SlackerThreadSafetyDoubleLock.getAaaa();
        Constructor<SlackerThreadSafetyDoubleLock> declaredConstructors = SlackerThreadSafetyDoubleLock.class.getDeclaredConstructor(null);
        declaredConstructors.setAccessible(true);//ignore
        //In the Java reflection mechanism, the private structure obtained through getdeclaraedconstructor can be accessed violently. If you want to access, please open the permission to [true]
        SlackerThreadSafetyDoubleLock a3 = declaredConstructors.newInstance();
        //The two objects are different
        System.out.println(a2);
        System.out.println(a3);

    }
}

However, the synchronization lock of a thread is resource consuming. If the object is obtained frequently in the program, the efficiency will be greatly reduced. Therefore, the method of adding synchronization lock in a single example is more suitable for the case where the object is not obtained very frequently.

starving

/**
 * @author zhang yifan
 * @version 8.0
 * @description:Starving singleton (thread safe)
 * @date 2021/12/2 16:55
 */
public class Hungry {
    /* You don't have to create objects. Pay attention*/
    private Hungry(){
    }
    private final  static Hungry HUNGRY=new Hungry();//Note constant capitalization
    public static  Hungry getInstance(){
        return HUNGRY;
    }
}

5. Hungry Han static thread safety
6. Enumeration singleton mode
7. Static inner class

/**
 * @author zhangyifan
 * @version 8.0
 * @description:Static internal classes (delay loading when instances consume resources) external classes do not need to load internal classes immediately. If internal classes are not loaded, install will not be initialized, so it does not occupy memory.
 * @date 2021/12/2 18:54
 */
public class Holder {
    private Holder (){

    }
    public static Holder getInstance(){
        return InnerClass.HOLDER;
    }
    public static class InnerClass{
        private static final Holder HOLDER=new Holder();
    }
}

(delay loading is implemented when the instance consumes resources)

summary

Tip: here is a summary of the article:
For example, the above is what we want to talk about today. This paper only briefly introduces the use of pandas, which provides a large number of functions and methods that enable us to process data quickly and conveniently.

Posted by FadeOut79 on Thu, 02 Dec 2021 18:32:08 -0800