您的位置:首页 > 其它

设计模式学习--单件模式(Singleton Pattern)

2013-06-06 19:41 246 查看

设计模式学习--单件模式

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;
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: