Singleton模式(单例模式)学习

图解设计模式之第三部分生成实例第五章Singleton模式学习


目录

图解设计模式之第三部分生成实例第五章Singleton模式学习

一、Singleton模式(也就是单例模式,只有一个实例。)

二、示例程序

类图:

Singleton类

Main类

三、Singleton模式中的登场角色

四、拓展思维的要点

五、相关的设计模式

六、练习题


 

 

一、Singleton模式(也就是单例模式,只有一个实例。)


程序在运行时,通常都会生成许多实例。例如表示字符串的java.lang.String类的实例与字符串是一对一的关系,所以当有1000个字符串的时候,会生成1000个实例。

但是,当我们想在程序中表示某个东西只存在一个时,就会有“只创建一个实例的”需求。典型的例子有表示程序所运行于的那台计算机的类、表示软件系统相关设置的类,以及表示视窗系统的类。

当然,只要我们在编写程序的时候多加注意,确保只调用一次new MyClass(),就可以达到只生成一个实例的目的。

  • 想确保任何情况下都绝对只有一个实例
  • 想在程序上表现出“只存在一个实例

像这样确保只生成一个实例的模式被称作Singleton模式。Singleton是指含有一个元素的集合。因为本模式值生成一个实例,一次以Singleton命名。

二、示例程序


首先我们看一段Singleton模式的示例程序。

名字说明
Singleton

只存在一个实例的类

Mainc测试程序行为的类

 

类图:

先说明一下:UML图规则中构造函数Singleton前带有“-”,表示Singleton方法是private,带下划线表示给方法是static方法。

Singleton
-singleton

-Singleton

+getInstance

Singleton类

Singleton类只会一个实例。Singleton类定义了static字段singleton,并将其初始化为Singleton类的实例。初始化的行为仅在该类被加载时进行一次。

Singleton类的构造方法是Private的,这是为了禁止从宏观Singleton类的外部调用构造方法。如果从Singleton类以外的代码中调用构造方法new Singleton(),就会出现编译错误。如果程序十分小心,不会使用new关键字生成实例,就不需要定义构造方法为private。但是这样的话,Singleton模式就没有意义了。Singleton模式的作用在于可以确保任何情况下都只能生成一个实例。为了达到这个目的,必须设置构造方法为private。

以下为Singleton类的代码:

public class Singleton{
    private static Singleton singleton = new Singleton();
    private Singleton(){
        System.out.println("生成一个实例。");
    }
    public static Singleton getIntance(){
        return singleton;
    }
}

Main类

Main类使用了Singleton模式。在Main类中,我们调用了两次Singleton类的getIntance方法,来获取Singleton类的实例,并将返回值分布保存在obj1和obj2中。然后通过表达式obj1 == obj2 是否成立来判断obj1 和obj2 是否为同一个实例。

Main代码如下:

public class Mian {
    public static void main(String[] args) {
        System.out.println("Start.");
        Singleton obj1 = Singleton.getIntance();
        Singleton obj2 = Singleton.getIntance();
        if( obj1 == obj2){
            System.out.println("obj1与obj2是相同的实例。");
        }else{
            System.out.println("obj1与obj2是不同的实例。");
        }
        System.out.println("End.");
    }
}

运行结果如下:

Start.
生成一个实例。
obj1与obj2是相同的实例。
End.

三、Singleton模式中的登场角色


在Singleton模式中有以下登场角色。

  • Singleton

在Singleton模式中,只有Singleton这一个角色。Singleton角色中有一个返回唯一实例的static方法。该方法总是会方法同一个实例。

四、拓展思维的要点


  • 为什么必须设置值限制

Singleton模式对实例的数量设置了限制。为什么要在程序中特意设置这个现在呢?设置限制其实是为了程序增加一项前提条件。

当存在多个实例时,实例之间相互影响,肯会产生意想不到的Bug。

但是,如果我们可以确保只有一个实例,就可以在这个前提下放心的编程了。

  • 何时生成这个唯一的实例

如果你稍微注意一下程序的运行结果就会发现,在“Start.”之后就显示出了“生成了一个实例。”

程序运行后,在第一次调用getIntance方法时,Singleton类会被初始化。也就是在这个时候,static字段singleton被初始化,生成了唯一的一个实例。

五、相关的设计模式


在一下设计模式中,多数情况下只会生成一个实例。

  • AbstrsctFactory(抽象工厂)模式
  • Builder(建造者模式)模式
  • Facade(外观模式)模式
  • Prototype(原型模式)模式

在以上的学习中我们学习了确保只能生成一个实例的Singleton模式。我们在Singleton模式中定义了用于获取唯一一个实例的static方法,同时为了防止不小心使用new关键字创建实例,还将构造方法设置为private。


六、练习题

练习题一

在下面的TicketMaker类中,每次调用getNextTicketNumber方法都会返回1000,1001,1002...的数列。我们可以用它生成票的编号或是其他序列号。在现在该类的实现方式下,我们可以生成多个该类的实例。请修改代码,运用Singleton模式确保只能生成一个该类的实例。

非Singleton模式的TicketMaker类(TicketMaker.java)

public class TicketMaker {
    private int ticket = 1000;
    public int getNextTicketNumber() {
        return ticket++;
    }
}

练习题二

请编写Triple 类,实现最多只能生成三个Triple类的实例,实例编号分别为0、1、2且可以通过getInstance(int id)来获取该编号对应的实例。

练习题三

某位开发人员编写了如下的Singleton类。但这并非严格的Singleton模式。请问这是为什么呢?

代码如下:

public class Singleton {
    private static Singleton singleton = null;
    private Singleton() {
        System.out.println("生成了一个实例。");
    }
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

(提示:这题与多线程有关。)

 

以上内容转载自《图解设计模式》一书,是个人学习时作的笔记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值