当前位置:主页 > 查看内容

浅谈设计模式及Singleton

发布时间:2021-07-25 00:00| 位朋友查看

简介:目录 前言 设计模式design pattern 设计模式分类 一、创建型模式 二 、结构型模式 三、行为型模式 Singleton Pattern单例模式 饿汉式 懒汉式 双重判断 静态内部类 枚举式 前言 在我们平时的工作学习中代码的整洁与高可用会让程序更加有效率对项目的好处不言……

前言

在我们平时的工作学习中,代码的整洁与高可用会让程序更加有效率,对项目的好处不言而喻。

设计模式的学习会让我们的编程水平得到很大的提升,同时也有助于对框架的理解,因为优秀的框架结构都用到了设计模式。

今天先瞅瞅单例模式,剩余的设计模式我也会慢慢更新,做一个系列。


设计模式(design pattern)?

设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 是对面向对象设计中反复出现的问题的解决方案

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

Java设计模式贯彻的原理是:面向接口编程,而不是面向实现。其目标的原则是:降低耦合,增强灵活性。

设计模式分类:

一、创建型模式

创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其关联对象的创建、组合和表示方式。

所有的创建型模式都有两个主要功能:

  1. 将系统所使用的具体类信息封装起来;
  2. 隐藏类的实例是如何被创建和组织的。外界对于这些对象只知道他们共同的接口,而不清楚其具体的实现细节。

常见的创建型模式:

  • 单例模式(Singleton Pattern)
  • 工厂方法模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype pattern)

二 、结构型模式

结构型模式讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象实现新的功能(对象结构型模式)。

常见结构型模式:

  • 代理模式(Proxy)
  • 装饰模式(Decorator)
  • 适配器模式(Adapter)
  • 组合模式(Composite)
  • 桥梁模式(Bridge)
  • 外观模式(Facade)
  • 享元模式(Flyweight)

三、行为型模式

行为型模式关注的是对象的行为,用来解决对象之间的联系问题。

常见行为型模式:

  • 模板方法模式(Template Method)
  • 命令模式(Commend)
  • 责任链模式(Chain of Responsibility)
  • 策略模式(Strategy)
  • 迭代器模式(Iterator)
  • 中介者模式(Mediator)
  • 观察者模式(Observer)
  • 备忘录模式(Memento)
  • 访问者模式(Visitor)
  • 状态模式(State)
  • 解释器模式(Interpreter)

Singleton Pattern(单例模式)?

定义:Ensure a class has only one instance, and provide a global Point of access to it.
确保一个类只有一个实例存在。

最好学习方法就是分析代码:

饿汉式

/**
 * 饿汉式(类加载时,就进行对象实例化)
 * 类加载到内存后,就实例化一个单例,JVM保证线程安全
 * 类只加载一次,实例化一次   Class.forName()
 * 缺点:类完成加载,就完成实例化
 */
public class Manager01 {
	//private确保构造方法无法被外界实例化
    private Manager01(){
    }
    //静态常量(或变量)
    private static final Manager01 INSTANCE = new Manager01();
	//通过该方法获得实例
    public static Manager01 getInstance(){
        return INSTANCE;
    }
	//其余业务方法
    public void useOthers(){
    }

    public static void main(String[] args) {
    	
        Manager01 instance1 = Manager01.getInstance();
        Manager01 instance2 = Manager01.getInstance();
		//输出结果为True,同一个对象
        System.out.println(instance1==instance2);
    }
}

懒汉式

/**
 * 懒汉式(第一次引用类时,才进行对象实例化)
 * Lazy Loading
 * 按需初始化,但要保证多线程并发安全
 */
public class Manager02 {
    private Manager02(){}
    private static Manager02 INSTANCE;

    public static Manager02 getInstance(){
    //public static synchronized Manager02 getInstance()
    //加锁亦可在方法上,保证同步,多线程容易发生创建多个实例
        synchronized (Manager02.class){
        	//判断是否已实例化
            if (INSTANCE==null){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                INSTANCE = new Manager02();
            }
            return INSTANCE;
        }
    }
	//业务方法等
    public void useOthers(){}

    public static void main(String[] args) {
    	//创建100个线程,结果只有一个实例被创建
        for (int i = 0; i < 100; i++) {
            //lambda表达式
            new Thread(()->{
                System.out.println(Manager02.getInstance().hashCode());
            }).start();
        }
    }
}

双重判断

懒汉式模式会加锁,导致效率降低,双重模式是对懒汉的优化

/**
 * 双重判断
 */
public class Manager03 {
    private Manager03(){}
    private static Manager03 instance;

    public static Manager03 getInstance(){
        
        //判断第一次,若实例已存在,直接跳转返回instance。无需等待锁的释放
       if (instance==null){
           synchronized (Manager03.class){
           	    //二次判断,若此时已存在实例,就跳过if块
               if (instance==null){
                   try {
                       Thread.sleep(10);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   
                   instance = new Manager03();
                   return instance;
               }
           }
       }
       return instance;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(Manager03.getInstance().hashCode());
            }).start();
        }
    }
}

静态内部类

/**
 * 静态内部类
 * 加载外部类时不会加载内部类,懒加载
 */
public class Manager04 {
    private Manager04(){}

    private static class managerHolder { 
        private final static Manager04 INSTANCE = new Manager04();
    }

    public static Manager04 getInstance(){
        return managerHolder.INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(Manager04.getInstance().hashCode());
            }).start();
        }
    }
}

枚举式

/**
 * 枚举单例
 * 大佬写的,不仅解决线程同步,还可以反序列化
 * 完美
 */
public enum Manager05 {

    INSTANCE;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(Manager05.INSTANCE.hashCode());
            }).start();
        }
    }
}

最常用最简单的就是饿汉式,懒汉式了。

上面示例为看视频总结手敲,很精妙

;原文链接:https://blog.csdn.net/qq_44438746/article/details/115799490
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:java生成随机字符串的两种方法 下一篇:没有了

推荐图文


随机推荐