很多小伙伴,不知道设计模式是什么?
通常我们所说的设计模式是一种设计方案,是前人留下的经验及最佳实践。
想要学习设计模式,至少要把面向对象的基本结构全部了解。
设计模式,是建立在一定基础上的思维训练。
学习设计模式,要有面临痛苦的决心。
学会设计模式,对解决问题及对程序理解有更高层次的认识。
如果有这样的决心,那么下面我们就认识一下,它的真面目。
常说的设计模式是23种设计模式,分为3大类:
创建型模式5种:工厂方法、抽象工厂、单例、建造者、原型
结构型模式7种:适配器、代理、桥接、装饰者、外观、享元、组合
行为型模式11种:模板方法、解释器、策略、观察者、迭代器、职责链、命令、备忘录、状态、访问者、中介者。
当然有一部分模式中,还有一些小的变化,在未来的持续更新中,我们会一一列举,并以代码为主,去学习设计模式。
上次咱们说了“抽象工厂模式”。今天咱们来说“单例模式”。
单例模式-属于创建类型的一种常用的软件设计模式。单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
单例模式-要点
在Java语言中,对于单例模式的设计给出了如下要点:
某个类只能有一个实例。
它必须自行创建这个实例。
它必须自行向整个系统提供这个实例。
具体体现:
单例模式的类只提供私有的构造函数。
类定义中含有一个该类的静态私有对象。
该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对
“单例模式”从字面上理解,主要是“单一实例”。也就是说,无论谁调用,无论在哪里调用,始终保持只有一个实例。
重点步骤:
- 私有化构造函数方法,目的是不能让外部直接实例化对象。
- 构建对外方法,控制外部调用。
- 始终保持一个实例化对象调用,要用到静态空间。
看到上面的步骤,是不是觉得核心思路和“属性封装”的思路类似?
单例模式主要分类:
- 饿汉模式
“饿汉模式”主要意思是,利用静态变量实例化对象,利用方法返回当前所在类的静态变量。
而静态成员变量随着类的信息在程序结束前始终驻留于内存中,故而称为“饿汉”。如果单线程使用频繁用“饿汉模式”。
- 懒汉模式
“懒汉模式”主要意思是,利用静态变量为空,利用方法判断是否为空,如果为空就实例化对象,不为空就返回当前对象。从而保持始终访问同一个对象。
“懒汉”不打不动,不调用没有对象,调用一次后,始终实用一个对象。无愧于“懒”这个字。通常单线程程序,用“懒汉模式”。
- 双重检索模式
“双重检索模式”是针对多线程环境的线程安全性,从懒汉模式中演变而来,实际上就是懒汉模式的升级,将懒汉模式的方法中加入“synchronized”。
“双检索单例模式”的写法变化:在“synchronized”之外和使用“synchronized”里都进行了“非空检查”,从而保证多线程环境下,始终保持一个实例化对象的建立。
很多小伙伴们记住了单例模式,但是不知道在哪里能用的到单例模式。就此问题说一句“了解其功能自然直到用在哪里”。
咱们假定一个场景需求:学生会给学生放电影。
1、在放电影的过程中,始终有一台放映机在放映。
2、电影要一个一个播放。
3、学生操作放映机,学生可以换,放映机不能换。
控制一个功能类在整体的程序中,始终保持一个实例化对象使用。遇见类似“放映机”这种类的情况,会将其设置为单例模式使用。
单例模式优缺点
优点:
你可以保证一个类只有一个实例。
你获得了一个指向该实例的全局访问节点。
仅在首次请求单例对象时对其进行初始化。
缺点:
违反了单一职责原则。 该模式同时解决了两个问题。
单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。
该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。
单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。