先说说为什么要开始学习设计模式
工作已经一年之久,很多时间心思大多都花在需求的完成上,需求的完成度很高,但是设计呢?
有没有考虑过你所实现的代码是否有设计在其中呢?
如果没有的话接下来和我一起学习设计模式哈~(不一定学习了设计模式就能提高你的设计,但是总归会有帮助)
什么是设计模式
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式的分类
按目的分类:
- 创建型:主要用于创建对象。
- 结构型:主要用于处理类或对象的组合。
- 行为型:主要用于描述对类或对象怎样交互和怎样分配职责。
按范围分类:(模式主要是用于处理类之间关系还是处理对象之间的关系)
- 类模型:处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,是属于静态的。
- 对象模型:处理对象间的关系,这些关系在运行时刻变化,更具动态性。
大概介绍了一些知识点,接下里我们进入设计模式的学习--单例模式
单例模式的定义
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 单例模式是一种对象创建型模式。
从他的定义我们可以看到有三个特点:
- 实例唯一
- 自行创建
- 全局访问
让我们看看单例模式的类图是什么样子
我们可以看到:一个私有的当前类型的成员变量,一个私有的构造方法,一个 getInstance 方法。创建对象不再通过new 而通过 getInstance 让该类自行创建。
接下来就是单例模式的实现啦
给大家介绍几种可用的单例模式的实现:
一 饿汉式(静态常量)
/**
* 饿汉式(静态常量)
*/
class Singleton {
private static final Singleton Instance = new Singleton();
static Singleton getInstance() {
return Instance;
}
private Singleton() {
}
}
优点:简单,使用时没有延迟;在类装载时就完成实例化,天生的线程安全
缺点:没有懒加载,启动较慢;如果从始至终都没使用过这个实例,则会造成内存的浪费。
二 饿汉式(静态代码块)
/**
* 饿汉式(静态代码块)
*/
class Singleton {
private static Singleton Instance;
static {
Instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return Instance;
}
}
这种是将类实例化的过程放在了静态代码块中,在类装载的时执行静态代码块中的代码,初始化类的实例。
优缺点同上。
三、双重检查(DCL)
/**
* 双重检查(DCL)
*/
public class Singleton {
private static volatile Singleton Instance;
private King() {
}
public static Singleton getKingInstance() {
if (Instance == null) {
synchronized (Singleton.class) {
if (Instance == null){
Instance = new Singleton();
}
}
}
return Instance;
}
}
优点:线程安全;延迟加载;效率较高。
缺点:JDK < 1.5 的时候不可用
现在大家基本都是jdk1.8,所以也不存在这个问题。那为什么不可用呢?大家可以学习一下哈
使用场景
我们学习了怎么实现,那什么时候我们需要采用单例模式呢?
单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。比如:
- 需要频繁实例化然后销毁的对象
- 创建对象时耗时过多或者耗资源过多,但又经常用到的对象
- 有状态的工具类对象
- 频繁访问数据库或文件的对象
给大家介绍下具体的使用场景:
- 比如网站的计数器,一般也是采用单例模式实现,否则难以同步
- 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制
- 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。主要是节省打开或者关闭数据库连接所引起的效率损耗
- ...
这是几个比较常用的,大家可以参考这些想一下在自己的项目中是否采用了单例模式呢?又或者哪里也可以使用单例模式呢?
概述
其实单例模式的实现还有其他的实现方式,比如线程安全等等的,但是根据各方面,效率等因素,不推荐使用。
所以我在这里就只总结几个推荐大家使用的单例模式的实现。希望对大家有用。