android设计模式之单例模式

本文介绍了单例模式的五种实现方法及其应用场景,包括懒汉模式、DCL模式、静态内部类模式、枚举模式和容器实现单例。每种方法都有其优缺点,适用于不同的项目需求。

单例模式可能是大家见得最多,应用最广泛,也是最简单的设计模式了,下面讲讲单例模式的几种实现方法以及每个实现方法的优缺点。

确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多资源,或者某种类型的对象只应该有且只有一个,例如:创建一个对象需要消耗资源过多,如访问IO和数据库等资源,这时就可以考虑用单例模式:

(一)懒汉模式

懒汉模式是声明一个静态对象,并且在用户第一次调用getInstance时进行初始化,见名思义,懒汉模式就是你需要时我才创建对象,下面是懒汉模式的代码实现:

/**
 * 单例模式--懒汉模式
 * @author hao
 *
 */
public class SingletonA {
	private static SingletonA instance;
	private SingletonA() {
	}
	public static synchronized SingletonA getInstance(){
		if(instance == null){
			instance = new SingletonA();
		}
		return instance;
	}
}


懒汉模式的优点是单例只有使用时才会被实例化,一定程度上节约了资源;缺点是每次加载都需要实例化,反应稍慢,最大的问题是每次调用getInstance时都进行了同步,造成不必要的同步开销,这种模式一般是不推荐使用的。

(二)Doubel Check Lock(DCL)实现单例

/**
 * 单例模式--DCL模式
 * @author hao
 *
 */
public class SingletonB {
	private static SingletonB instance = null;
	private SingletonB() {
	}
	public static SingletonB getInstance(){
		if(instance == null){
			synchronized (SingletonB.class) {
				if(instance == null){
					instance = new SingletonB();
				}
			}
		}
		return instance;
	}
}

DCL的优点是既能在需要时才初始化单例,又能保证线程安全,资源利用率高;缺点是在高并发环境下有一定缺陷;DCL模式是使用最多的单例模式!

(三)静态内部类单例模式

/**
 * 单例模式--静态内部类模式
 * @author hao
 *
 */
public class SingletonC {
	private SingletonC(){}
	public static SingletonC getInstance(){
		return SingletonHolder.sInstance;
	}
	/**
	 * 静态内部类
	 * @author hao
	 *
	 */
	private static class SingletonHolder{
		private static final SingletonC sInstance = new SingletonC();
	}
}
DCL模式虽然在一定程度上解决了资源消耗,多余的同步,线程安全等问题,但还是在某些情况下出现实效问题,静态内部类单例模式可代替使用,第一次调用getinstance会导致虚拟机加载singletonholder类,这种方式不仅能确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化,这种方法是推荐使用的单例模式。

(四)枚举单例模式

/**
 * 单例模式--枚举模式
 * @author hao
 *
 */
public enum SingletonD {
	INSTANCE;
	public void doSomething(){
		System.out.println("doSomething..");
	}
}
枚举实现最大的优点就是写法简单,最重要的是枚举实例的创建是线程安全的,在任何情况下都是一个单例。

(五)使用容器实现单例

/**
 * 使用容器实现单例模式
 * @author hao
 *
 */
public class SingletonE {
	private static Map objMap = new HashMap();
	private SingletonE() {
	}
	public static void registerService(String key,Object instance){
		if(!objMap.containsKey(key)){
			objMap.put(key, instance);
		}
	}
	public static Object getService(String key){
		return objMap.get(key);
	}
}
这种方式使我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了藕合度。

以上单例模式他们的核心原理都是将构造函数私有化,各自都有自己的优缺点,选择哪种方式实现取决于项目本身的需求!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值