精选十大设计模式--单例模式

什么是设计模式?

  • [ 设计模式:是一套被反复使用,多数人知晓的,经过分类的。前人代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码的可靠性、程序的重用性。]

1、 为什么要学习设计模式?

  • 看懂源码、看懂源码、看懂源码,不懂源码,你的代码之路很难!
  • 接盘。去了另外一家公司,接盘他人的项目,看别人的代码容易上手。
  • 规范自己的代码。有了规范,大家都好办事。

2、设计模式分类

  1. 创建型模式:(五种)工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  2. 结构型模式:(七种)适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  3. 行为型模式:(十一种)策略模式、模板方法模式、观测者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

3、设计模式的六大原则

  1. 开发封闭原则
  2. 里氏代换原则
  3. 依赖倒转原则
  4. 接口隔离原则
  5. 迪米特法(最少知道原则)
  6. 单一职责原则

4、 单例模式

4.1 什么是单例

保证一个类只有一个实例,并且提供一个访问该全局的访问点

4.2 那些地方用到了单例模式

  1. 网站的计算器;
  2. 应用程序的日志应用;
  3. 多线程的线程池的设计一般是采用单例模式;
  4. windows的任务管理器

4.3 单例防止反射漏洞攻击

package 设计模式.单例模式;

public class 单例防止反射漏洞攻击 {
    private static boolean flag = false;
    private 单例防止反射漏洞攻击(){
        if (flag == false){
            flag = !flag;
        }else {
            throw new RuntimeException("单例模式被侵犯!");
        }
        
    }

    public static void main(String[] args) {
        
    }
}

4.4 如何选择单例模式

如果不需要延迟加载单例模式,可以使用枚举或者饿汉式,相对来说枚举性好于饿汉式。如果需要延迟加载,可以使用加载,可以使用静态内部类或者懒汉式,相对来说静态内部类好于懒汉式,最好使用饿汉式!!!

5、单例创建方式

5.1 饿汉式

饿汉式:类初始化时,就会立即加载该对象,线程天生安全,调用效率高

package 设计模式.单例模式;

public class 饿汉式 {
    // 类初始化时,就会立即加载该对象,线程安全,调用效率高
    private static 饿汉式 person = new 饿汉式();

    private 饿汉式(){
        System.out.println("私有化构造器");

    }

    public static 饿汉式 getInstance(){
        return person;
    }


    public static void main(String[] args) {
        饿汉式 p1 = 饿汉式.getInstance();
        饿汉式 p2 = 饿汉式.getInstance();

        System.out.println(p1==p2);
    }
}

5.2 懒汉式

懒汉式:类初始化时,不会初始化该对象,真正需要使用的时候才会创建该对象,具备懒加载功能

package 设计模式.单例模式;

public class 懒汉式 {
    // 类初始化时,就会立即加载该对象,线程安全,调用效率高
    private static 懒汉式 person;

    private 懒汉式(){
        System.out.println("私有化构造器");
    }

    public synchronized  static 懒汉式 getInstance(){
        if(person == null){
            person = new 懒汉式();
        }
        return person;
    }

    public static void main(String[] args) {
        懒汉式 p1 = 懒汉式.getInstance();
        懒汉式 p2 = 懒汉式.getInstance();

        System.out.println(p1 == p2);//true
    }
}

5.3 静态内部类

静态内部类:结合了懒汉式和饿汉式各自的优点,真正需要的对象才会加载,加载类是线程安全的。

package 设计模式.单例模式;

public class 静态内部类 {
    private 静态内部类(){
        System.out.println("构造器私有化");
    }

    public static class SingletonClassInstance{
        private static final 静态内部类 person = new 静态内部类();
    }

    // 方法没有同步
    public static 静态内部类 getInstance(){
        return SingletonClassInstance.person;
    }

    public static void main(String[] args) {
        静态内部类 p1 = 静态内部类.getInstance();
        静态内部类 p2 = 静态内部类.getInstance();

        System.out.println(p1 == p2);
    }
}

5.4 枚举单例式

枚举单例式:
优点:实现简单、调用效率高,枚举本身就是单例,由jvm从根本上提供保障!避免通过反射和反序列化的漏洞。
缺点:没有延迟加载。

package 设计模式.单例模式;

public class 枚举单例式 {

    // 定义枚举
    private static enum Demo{

        INSTANCE;

        // 枚举元素为单例
        private 枚举单例式 person;

        private Demo(){
            System.out.println("枚举Demo私有构造参数");
            person = new 枚举单例式();
        }
        public 枚举单例式 getInstance(){
            return person;
        }
    }

    public static 枚举单例式 getInstance(){
        return Demo.INSTANCE.getInstance();
    }

    public static void main(String[] args) {
        枚举单例式 p1 = 枚举单例式.getInstance();
        枚举单例式 p2 = 枚举单例式.getInstance();
        System.out.println(p1 == p2);
    }
}

你可能感兴趣的:(设计模式,设计模式,java)