自学设计模式--1 单例模式
来源:互联网 发布:网店美工 编辑:程序博客网 时间:2024/06/05 09:31
写在前面
问:一个男人,从恋爱走向结婚,对于一个男人意味着什么?
答:牛进圈了,从此有了稳定的饲料来源,但想乱吃点别的什么就不太可能了……
1. 单例模式的定义
官方定义:Ensure a class has only one instance,and provide a global point of access to it.确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
2.单例模式的特点
优点:
- 由于在内存中只有一个实例,减少了内存开支,减少了系统资源的开销。
- 避免了对资源的多重占用;
- 可以优化和共享资源的访问;
缺点:
- 单例模式没有接口,扩展困难;
- 在并行的环境中,单例模式对测试不利;
3.单例模式的使用场景
在一个系统中,要求一个类有且仅有一个对象,如以下场景:
- 系统要求生成唯一序列号环境;
- 保存web页面上计数器的值,不必每次刷新都记录到数据库;
- 创建对象的实例耗费的资源比较多;
注意事项:
①解决线程不安全的问题:
单例模式有饿汉式和懒汉式两种方式,推荐使用饿汉式,懒汉式存在风险。饿汉式代码见关键代码的Emperor类,下面给出懒汉式代码,说明见注释。
package com.pbi.pattern.singleton;/** * 此种单例模式存在风险(饿汉式) * * @author 姓名 工号 * @version [版本号, 2013-5-13] * @see [相关类/方法] * @since [产品/模块版本] */public class EmperorI{ private static EmperorI emperor = null; private EmperorI() { super(); } /** * * <风险分析: * ①假设存在两个线程,线程A和线程B, * ②当线程A执行到 emperor = new Emperor时,正在申请内存分配, * 此时线程B执行到 if(null == emperor),此时的返回结果不确定是true还是false * 若是true,此时线程B 也创建了新的对象,导致业务逻辑的混乱> * @return * @see [类、类#方法、类#成员] */ public static EmperorI getInstance() { if (null == emperor) { emperor = new EmperorI(); } return emperor; } public static void say() { System.out.println("~~~ I am the Emperor XXX ~~~"); } }
②考虑对象的复制情况
单例模式类建议不要实现Cloneable接口,在Java中对象默认是不可以被复制的,实现了Cloneable接口,并重写了clone方法,则可以直接通过对象复制的方式创建一个新对象,对象复制是不用调用类的构造函数的,因此,即使是私有的构造函数,对象仍然可以被复制。
4.单例模式的使用案例
4.1描述
皇帝就是孤家寡人,皇帝类只能产生一个实例,所有对象对他的依赖都是相同的。
4.2类图
图1 单例模式类图
4.3关键代码
Emperor类
/** * 此种单例模式存在风险(懒汉式) * * @author 姓名 工号 * @version [版本号, 2013-5-13] * @see [相关类/方法] * @since [产品/模块版本] */public class EmperorII{ private static EmperorII emperor = new EmperorII(); private EmperorII() { super(); } public synchronized static EmperorII getInstance() { return emperor; } }
Minister类
package com.pbi.pattern.singleton;/** * 大臣类 * * @author 姓名 工号 * @version [版本号, 2013-5-13] * @see [相关类/方法] * @since [产品/模块版本] */public class Minister{ public static void main(String[] args) { EmperorI emperorI = EmperorI.getInstance(); emperorI.say(); EmperorI emperorII = EmperorI.getInstance(); emperorII.say(); EmperorI emperorIII = EmperorI.getInstance(); emperorIII.say(); } }
参考资料:《设计模式之禅》--秦小波
- 自学设计模式--1 单例模式
- 设计模式--单例模式【自学笔记】
- java自学之路-----继承 单例设计模式
- JAVA自学日记2--单例设计模式
- 模式设计1--单例设计模式
- 【设计模式】## 1、单例设计模式 ##
- 【笔记】设计模式 - 1 单例模式
- 设计模式(四)--单例模式(1)
- 设计模式(1)-单例模式
- 设计模式1-单例模式
- 设计模式(1) 单例模式
- 设计模式(1):单例模式
- 设计模式(1)---->单例模式
- 设计模式1 单例模式
- 设计模式(1):单例模式
- 设计模式(1):单例模式
- Java设计模式-1-单例模式
- 设计模式1--单例模式
- <link href ="css/index.css" rel="Stylesheet" type="text/css" />
- 一句话总结Windbg 32位版本和64位版本的选择
- IOS成长之路-实现界面切换和数据的传递
- Oracle Data Integrator 介绍
- uva 101 - The Blocks Problem
- 自学设计模式--1 单例模式
- Myeclipse中修改类及jsp文件后不用重启tomcat的方法
- restlet2.1 学习笔记(九)简单验证客户端用户名与密码
- UIView的剖析!
- c++ 处理大文件
- 【Android 开发教程】数据共享
- Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into
- 复印机的使用方法
- C++文件操作详解(ifstream、ofstream、fstream