三、创建型模式:单例模式(SINGLETON)
来源:互联网 发布:现代四大名著网络 编辑:程序博客网 时间:2024/06/05 23:59
俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Singleton,她们只要说道“老公”,都是指的同一个人,那就是我(刚才做了个梦啦,哪有这么好的事)
定义
有单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。
使用场景
当类只能有一个实例而且第三方可以从一个公共的访问点访问它时。
当一个唯一的实例可以通过子类化来扩展,而且第三方需要在不更改代码的情况下就能使用一个扩展的实例时。
优缺点分析
优点:
1.实例控制
对唯一的实例做出访问控制。
允许改变实例的数目,事实上单例模式只是实例有限的类的一种特列,通过计数等方式可以做到双例模式,三例模式等需要实例化有限次的类。
2.灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
缺点:
1.开销
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
2.可能的开发混淆
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
3.对象生存期
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。
单例模式UML图
应用场景及代码分析
在开头的时候提到梦中的时候梦到了自己有好多的老婆,有中国的老婆、有美国的老婆…(ps:在我们伟大的天朝里,可是施行一夫一妻、男女平等的婚姻制度)。为了给大家演示单例模式,我们假设有2个老婆,一个中国的老婆、一个美国的老婆,老公只有一个,老公要时常的陪妻子约会,妻子觉得单独和老公出去才是浪漫,所以她们都想老公只带自己出去约会。
首先我们先看一下老公的类,因为老公只有一个,所以老公我们使用单例模式创建,如下代码:
//单例,老公类public class Husband {//老公只有一个private static Husband instance;private Husband() {}public static Husband getInstance() {if (instance == null) {instance = new Husband();}return instance;}public void show(){System.out.println("老公可是一个安静的美男子!");}public void date(){System.out.println("美男子可以和亲爱的妻子约会了!");}}
两个老婆分别有找老公和约会的方法
//中国妻子类public class ChinaWife {private Husband myHusband = null;//找老公public void showHusband(){myHusband = Husband.getInstance();myHusband.show();}//和老公约会public void dateWithHusband(){myHusband = Husband.getInstance();myHusband.date();}}//美国妻子public class AmericanWife {private Husband myHusband = null;//找老公public void showHusband(){myHusband = Husband.getInstance();myHusband.show();}//和老公约会public void dateWithHusband(){myHusband = Husband.getInstance();myHusband.date();}}
实现了老公和妻子的代码以后,我们要开始测试了:
public class SingletonTest {public static void main(String[] args){AmericanWife amWife = new AmericanWife();System.out.println("美国妻子:我要找老公!");amWife.showHusband();System.out.println("美国妻子:老公和我约会吧!");amWife.dateWithHusband();ChinaWife chWife = new ChinaWife();System.out.println("中国妻子:我要找老公!");chWife.showHusband();System.out.println("中国妻子:老公和我约会吧!");chWife.dateWithHusband();}}
结果如下:
美国妻子:我要找老公!
老公可是一个安静的美男子!
美国妻子:老公和我约会吧!
美男子可以和亲爱的妻子约会了!
中国妻子:我要找老公!
老公可是一个安静的美男子!
中国妻子:老公和我约会吧!
美男子可以和亲爱的妻子约会了!
我们可以看到当两个妻子都能找到老公,老公是同一个人,而且都和老公约会了。
有一天,美国老婆希望老公和她出去约会,他心情愉悦,可是在他准备好好打扮自己的时候,中国妻子开开心心的跑了过来,“老公,和奴家约会去呗!”,这可怎么办啊,老公可没有韦小宝那么机灵,答应了美国老婆,可又不想让中国老婆失望,他陷入了思考之中!
在我们的老公的实例创建方法中,
if (instance ==null) {
instance =new Husband();
}
美国老婆申请了老公实例,这时候老公实例还没有创建,所以instance ==null,那么老公会创建出一个实例来,可是还没等老公创建出实例,中国老婆也过来申请老公了,这时候老公还是没有创建出来,所以instance还是null,老公还会创建出来,这样就创建出了2个老公实例,可老公明明就是1个啊。在我们的代码中,如果有多个线程同时访问老公创建实例的方法,就不满足我们单例模式的单例了。
我们需要为实例过程加锁,修改老公类:
//单例,老公类public class Husband {static Lock lock = new ReentrantLock();// 老公只有一个private static Husband instance;private Husband() {}public static Husband getInstance() {//这里判断是为了防止频繁的进行加解锁if (instance == null) {//加上锁lock.lock();//创建实例,并且能够防止多次创建实例if (instance == null) {instance = new Husband();}//解锁lock.unlock();}return instance;}public void show() {System.out.println("老公可是一个安静的美男子!");}public void date() {System.out.println("美男子可以和亲爱的妻子约会了!");}}
- 三、创建型模式:单例模式(SINGLETON)
- Singleton---单例模式(创建型)
- 创建型:单例模式(singleton)
- 创建型模式--单例模式(Singleton)
- 创建型模式-单例模式(singleton)
- 单例模式(Singleton)(对象创建型模式)
- 创建型模式之单例模式(Singleton)
- 创建型模式-----单例模式(Singleton)
- 创建型模式1:单例模式(Singleton Pattern)
- 【创建型模式一】单例模式(Singleton)
- 创建型模式:单例模式(SINGLETON)
- 十二、单例模式Singleton(创建型模式)
- (创建型模式)SINGLETON——单例模式
- 设计模式-创建型-单例模式(Singleton)
- Singleton模式(单例模式 创建型)
- 设计模式--单例模式Singleton(创建型)
- 创建型模式:单例模式(Singleton)
- 创建型 - Singleton单例模式 (转)
- Autolayout进阶
- leetcode——Triangle
- 第十三周项目1.4 折腾数组(4)选择性输出组合新数组
- 关于swing界面创建以及窗口放在屏幕中央的方法
- 《数据结构》第五章 树和二叉树 思维导图
- 三、创建型模式:单例模式(SINGLETON)
- Myeclipse快捷键
- ios编译openssl曲折的过程纪录
- C#.net VSTO Excel开发中一些常用方法
- ebs表结构(转)
- 有时候,一个项目真的是挺复杂的,就说下这个吧
- 关于CEdit中的LineLength和LineIndex的使用
- 第十三周项目1.5 折腾数组(5) 在数组中插入新数值
- 定制自己的eclipse 的5个小提示