# 单例模式
[TOC]
## 什么是设计模式
>[info] 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
> **设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结**。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案。
**通俗解释就是:**
>[info] 设计模式类似于我们做数学应用题时,针对不同的题型,总结出来的不同的解题套路。灵活的运用了不同的公式(就是我们学习到的Java知识点),给这些应用题制定了规范而又简单的解题方法
## 设计模式的使用
设计模式在软件开发中的两个主要用途。
**开发人员的共同平台**
设计模式提供了一个标准的术语系统,且具体到特定的情景。例如,单例设计模式意味着使用单个对象,这样所有熟悉单例设计模式的开发人员都能使用单个对象,并且可以通过这种方式告诉对方,程序使用的是单例模式。
**最佳的实践**
设计模式已经经历了很长一段时间的发展,它们提供了软件开发过程中面临的一般问题的最佳解决方案。学习这些模式有助于经验不足的开发人员通过一种简单快捷的方式来学习软件设计。
## 23种设计模式
设计模式多种多样,通常认为23种设计模式是其他设计模式的基础。
创建型模式:简化创建对象的过程
结构型模式:在软件上通过重构,抽象使结构变得更有条理
行为型模式:在现实中具体的业务场景中对某种行为进行的优化
## 单例模式
在实际的开发中,绝大部分的服务性质的类都会设计成单例模式
所谓的单例模式,就是类**只有**(**只产生**)一个对象,外部要使用该类的对象,通过调用一个类方法实现。
比如说,我们打印机连接电脑,无论多少的打印机与电脑相连,实现操作控制的只能是一台电脑。如果一台打印机连接两台电脑,这两台电脑都对打印机作出指示,就会打印出错。
### 单例模式特点
* 1、单例类只能有一个实例。
* 2、单例类必须自己创建自己的唯一实例。
* 3、单例类必须给所有其他对象提供这一实例。
![](https://img.kancloud.cn/28/5b/285b94a3e7d0840bc973f768848e3aba_985x466.png)
### 单例模式实现
#### 饿汉式
特点:创建对象实例的时候直接初始化,速度快,占用空间大。-对象已经优先创建好了
~~~
//饿汉式:创建对象实例的时候直接初始化 空间换时间
public class SingletonOne {
//1、创建类中私有构造
private SingletonOne() {
}
//2、创建该类型的私有静态实例,先实例化,这个饿汉式的特点
private static SingletonOne instance=new SingletonOne();
//3、创建公有静态方法返回静态实例对象
public static SingletonOne getInstance() {
return instance;
}
}
~~~
#### 懒汉式
特点:类内实例对象创建时并不直接初始化,直到第一次调用getInstance()方法时,才完成初始化操作,时间长,空间小-只有在用到的时候才会进行对象创建
~~~
public class SingletenTwo {
//1、创建私有构造方法
private SingletenTwo(){};
//2、创建该类型的私有静态实例
private static SingletonTwo instance=null;
//3、创建公有静态方法返回静态实例对象
public static SingletonTwo getInstance(){
if(instance == null) {
instance=new SingletonTwo();
}
return instance;
}
}
~~~
### 饿汉式PK懒汉式
1. 饿汉式在类加载时就实例化对象,空间换时间,在第一次使用此实例的时候加载速度快,但长时间不使用该对象则造成内存空间的浪费。懒汉式在第一次真正使用此类实例的时候才实例化,时间换空间,在第一次使用此类实例的时候加载速度慢,但不会造成内存空间的浪费。
2. 在多线程中,饿汉式线程安全,懒汉式存在线程风险。
### 单例模式的特点及适用场景
优点:
![](https://img.kancloud.cn/95/17/951774a452ba14a148630888cf49a80b_516x380.png)
缺点:
![](https://img.kancloud.cn/48/f9/48f99d9e3479aac16cf13e8caf1f4c92_517x384.png)
使用场景:
![](https://img.kancloud.cn/f2/39/f239484125d888406d7f443569b66e4c_886x311.png)
## 练习
一、选择
1. 单例模式的实现必须满足()个条件(多选)
~~~
A. 类中的构造方法的访问权限必须设置为私有的
B. 类中的构造方法必须用protected修饰
C. 必须在类中创建该类的静态私有对象
D. 在类中提供一个公有的静态方法用于创建、获取静态私有对象
~~~
2. 下列关于懒汉式和饿汉式的说法错误的是(多选)
~~~
A. 饿汉式在第一次使用时进行实例化
B. 懒汉式在类加载时就创建实例
C. 饿汉式的线程是安全的
D. 懒汉式存在线程风险
~~~
二、编程
1. 某公司研发星球维护系统,请使用饿汉式单例模式的实现思想,设计编写地球类。
程序运行参考效果图如下:
![](https://img.kancloud.cn/c8/4a/c84a4c25b27773e7dd63351bf9360504_395x287.png)
~~~
public class Earth {
//定义私有构造方法,并在构造方法中打印输出“地球诞生”
//定义私有静态类对象并完成实例化
//定义公有静态方法返回类内的私有静态对象
}
~~~