设计模式6——单例模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

单例模式(Singleton)

是一种创建型模式。

目录

一、概述

二、如何使用

三、举例---懒汉式

四、举例---饿汉式


一、概述

1、保证一个类仅有一个实例,并提供一个访问它的全局访问点;
2、在一些场景下,类的实例化应该由自己决定,而不是外部决定的;
3、通常我们可以定义一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的方法就是,让此对象自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法;
4、单例模式封装了他的唯一实例,所以它可以严格地控制客户怎样访问它以及何时访问它。简单地说就是对唯一实例的受控访问。

1.1、主要的角色只有一种:

  • 需要使用单例模式的对象(单个):其中实现方式有两种,分为懒汉式饿汉式

1.2、从上述理论看出使用单例模式主要有2点:

  • 这个对象,它应当可以自己实例化自己
  • 同时它应当不可以被其他对象实例化

1.3、直观的理解上这个对象的关系情况如下:

1.4、从技术实现的角度看,对象的UML图如下:

二、如何使用

  • 隐藏它的构造方法,使得其他对象无法实例化它
  • 给它自己定义一个获取它自己实例的接口,供其他对象使用

三、举例---懒汉式

(用Java实现)

懒汉式单例:

//懒汉式单例
public class Singleton1 {
    private volatile static Singleton1 instance; //volatile修饰,用来避免一些多线程场景下的问题

    private Singleton1() {//将构造函数私有化,禁止其他对象实例化它自己
    }

    //使得其他类可以得到该实例
    public static Singleton1 getInstance() {  //用static修饰的方法可以直接通过 类名.方法名 去访问,而无需new对象
        if (instance == null) {    //实例化被延迟到第一次访问时,并且之后再访问就不会再实例化了
            synchronized (Singleton1.class) { //synchronized修饰,用来避免一些多线程场景下的问题
                if (instance == null) {
                    System.out.println("实例化Singleton1"); //标记一下,用来在测试的时候判断被实例化了几次
                    instance = new Singleton1();
                }
            }
        }
        return instance;
    }
}

 主程序(发起请求的类):

public class Main {
    public static void main(String[] args) {
        //懒汉式
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s2 = Singleton1.getInstance();
        System.out.println(s1 == s2);

        //饿汉式
//        Singleton2 s3 = Singleton2.getInstance();
//        Singleton2 s4 = Singleton2.getInstance();
//        System.out.println(s3 == s4);
    }
}

四、举例---饿汉式

(用Java实现)

饿汉式单例:

//饿汉式单例
public class Singleton2 {
    //被static修饰的代码,在程序初始化阶段时就会运行此代码,并且只运行一次,这样保证了只有一个实例
    private static Singleton2 instance = new Singleton2();

    private Singleton2() {//将构造函数私有化,禁止其他对象实例化它自己
    }

    //使得其他类可以得到该实例
    public static Singleton2 getInstance() {
        return instance;
    }
}

 主程序(发起请求的类):

public class Main {
    public static void main(String[] args) {
        //懒汉式
//        Singleton1 s1 = Singleton1.getInstance();
//        Singleton1 s2 = Singleton1.getInstance();
//        System.out.println(s1 == s2);

        //饿汉式
        Singleton2 s3 = Singleton2.getInstance();
        Singleton2 s4 = Singleton2.getInstance();
        System.out.println(s3 == s4);
    }
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞吧!如果有建议,也请评论指教和讨论!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值