设计模式学习--单件模式
2013年6月6日 高考前一天 六六大顺
6月7、8号,录取吧!!!
设计模式继续学习,无聊的考试,让我少了很多学习的时间,下面学习所有模式当中最简单的单件模式,有的版本叫做单例模式,还有的叫做单态模式,不管怎么叫,我们只要原理就足够了,就好像说,乌龟和王八,难道换了个叫法就认不出来了?嗯,我喜欢叫王八。
这个模式似乎没有产生新的设计原则,不过还是回顾以下吧:
1. 封装变化
2. 多用组合,少用继承
3. 针对接口编程,不针对实现编程
4. 为交互对象之间的松耦合设计而努力
5. 类应该扩展开放,对修改关闭
6. 依赖抽象,不要依赖具体类
单例模式---确保一个类只有一个实例,并提供全局访问点。
要点:
- 单件模式确保程序中一个类最多只有一个实例。
- 单件模式也提供访问这个实例的全局点。
- 在Java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
- 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程问题(我们必须认定所有的程序都是多线程的)。
- 如果不采用第5版的Java 2,双重检查加锁实现会失效。
- 小心,你如果使用多个类加载器,可能导致单件失效而产生多个实例。
- 如果使用JVM 1.2或之前的版本,你必须简历单件注册表,以免垃圾收集器将单件回收。
package singleTonPattern;
/**
* 2013/6/6
*
* @author wwj 单例模式
*/
public class Singleton {
// 利用一个静态变量来记录Singleton类的唯一实例
private static Singleton uniqueInstance;
// 把构造器声明为私有的,只有自Singleton类内才可以调用构造器
private Singleton(){};
/**
* 用这个方法实例化对象,并返回这个实例
* @return
*/
public static Singleton getInstance() {
if(uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
/**
* 使用同步的方法,解决多线程灾难
* 但这种方法会影响程序执行效率
* @return
*//*
public static synchronized Singleton getInstance() {
if(uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}*/
/**
* 使用“急切”创建实例,而不用延迟实例化的做法
*/
/* private static Singleton uniqueInstance = new Singleton();
public static Singleton getInstance() {
return uniqueInstance;
}*/
/**
* 用“双重检查加锁”,在getInstance()中减少使用同步
* 如果性能是你关心的重点,这种做法可以帮你大大减少getInstance()的时间耗费
*/
/*private volatile static Singleton uniqueInstance;
public static Singleton getInstance() {
if(uniqueInstance == null) {
synchronized (Singleton.class) {
if(uniqueInstance == null) {
uniqueInstance = new Singleton;
}
}
}
}*/
}
使用实例:巧克力工厂
package singleTonPattern;
/**
* 巧克力工厂
* @author wwj
* 使用单实例对象
* 经典的单件模式,不适用于多线程的情况,因为可能会产生多个不同的对象,解决办法,实现同步方法
*/
public class ChocolateBoilder {
private boolean empty;
private boolean boiled;
private static ChocolateBoilder unqueInstance;
public ChocolateBoilder() {
empty = true;
boiled = false;
}
/**
* 确保一个类只有一个实例,并提供一个全局访问点
* @return
* 如果要解决多线程问题的话,可以将这个方法声明为Sychronized
*/
public static ChocolateBoilder getInstance() {
if(unqueInstance == null) {
unqueInstance = new ChocolateBoilder();
}
return unqueInstance;
}
public void fill() {
if(isEmpty()) {
empty = false;
boiled = false;
// 在锅炉内填满巧克力和牛奶的混合物
}
}
public void drain() {
if(!isEmpty() && !isBoiled()) {
//排除煮沸的巧克力和牛奶
empty = true;
}
}
public void boil() {
if(!isEmpty() && !isBoiled()){
// 将炉内物煮沸
boiled = true;
}
}
public boolean isEmpty() {
return empty;
}
public boolean isBoiled() {
return boiled;
}
}