单例模式应该说是从事开发的程序员都应该熟捻于胸的“最最低级”的设计模式。 工作中常用的到场景。
1.便于管理只实例化类的一个对象。
2.实例化对象较耗费资源。资源有限做单例处理。
上代码:
package com.jerome.designpattern;
public class Singleton {
public static Singleton mSingleton = new Singleton() ;
public static Singleton getInstance() {
return mSingleton ;
}
}
在接触的不少面试的童鞋中很多人都是这么写的。总结这种写法的一个原因是,写出这种程序的“伪程序猿们”认为单例是程序猿们为了遵守单例原则而写出的一种模式。这个假设的一个前提是:所有使用该类的程序员们都了解该类的使用原理。但是,这个前提是不一定是存在的,因为层次原因,可能会有一个同事在同一个包中new出无所个实例。
作为小组负责人,在做代码review的时候常常看到类似的代码------滥用访问修饰符,很多时候都是随手写一个public,private.其实,这种写法是很忌讳的。一旦将private的方法变成public,可能就违反了封装原则,如果这段代码是你一直负责,那么短时间内肯定没什么问题,但是,一旦协同作战,或者,新人加入的时候,可能就会很认真的考虑Why?,把方法暴露出来的目的是什么,这样就增加了理解的难度。同样,一个适合公开的代码,访问修饰符写成private,那么后期扩展的时候,说不定会有人修改你的代码,因为你写的时候是private,所以你可能不会为方法公开做某些特殊的处理,那么修改你代码的同事可能就会陷入你的逻辑漩涡中。
好了,废话不说,其实更多的单例模式应该是懒加载模式。如下代码所示:
package com.jerome.designpattern;
public class Singleton {
public static Singleton mSingleton = null ;
public synchronized static Singleton getInstance() {
if( mSingleton == null ) {
mSingleton = new Singleton();
}
return mSingleton ;
}
/**
* 构造方法私有化
*/
private Singleton() {
//。。。。。
}
}
这段代码才是单例模式的标准写法。
这里用到了synchronized关键字,其实它只是在第一次初始化实例的时候才有效,其他的大部分时间是冗余的。这里就引出了另一种模式:Double checked Locking.也许下面的代码你会很熟悉。
package com.jerome.designpattern;
public class Singleton {
private static Singleton instance ;
public static Singleton getInstance() {
if( instance == null ) {
synchronized (Singleton.class) {
if( instance == null ) {
instance = new Singleton() ;
}
}
}
return instance ;
}
private Singleton() {
System.out.println("hashCode is "+hashCode());
}
}
看似没有问题,但是这段代码在 这里被证明是有问题的。ok。其实能写到这里应该算是比较perfect了,但是根据官方的提示, 应该再加一个关键字volatile。