ps:第一个博客其实没有什么思路,不可能从activity生命周期说起吧23333。
先简单说说设计模式,其实实际的项目中用到的设计模式真的不多。她更像是那种温柔似水的女孩,和她在一起的点点滴滴会渐渐的改变你的生活,或者说是写代码的思路。通常只会在写完项目后总结的时候才会发现。。啊嘞??我居然用了这么多设计模式啊!!
ok,上主角。单例模式嘛,顾名思义只有一个就是单例。想像一下场景,全世界只有我一个男人就好了哈哈哈哈!
直接上代码:
public interface Person {
void eat(); //人总要吃饭吧?
}
public class Woman implements Person{
@Override
public void eat() {
}
}
上面是一个接口人,和一个女人的类。那男人怎么写呢??
public class Men implements Person{
/**
* 为了只有一个男人能造出来
* 只能委屈委屈构造函数,给她private了
*/
private Men(){}
/**
* 唯一的男人,就是funky我
*/
private static final Men funky = new Men();
/**
* 暴露出来一个方法,让别人使用
*
* @return
*/
public static Men getFunky() {
return funky;
}
@Override
public void eat() {
}
}
上面就是典型的 饿汉型单例,其实我一直不理解为什么叫饿汉。可能我理解能力有点问题吧233。 这种方法一看就有一个问题,第一次加载的时候我funky已经加载出来了,也算是一种浪费了。那唯一的男人funky这个类还能怎么写呢?
public class Men implements Person {
//第一次加载类的时候并不会实例化
private static Men funky = null;
/**
* 为了只有一个男人能造出来
* 只能委屈委屈构造函数,给她private了
*/
private Men() {
}
public static Men getFunky() {
if (null == funky) {//判空
funky = new Men();
}
return funky;
}
@Override
public void eat() {
}
}
经典的
懒汉型单例的写法,它也有缺点。。饿,第一次调用get()的时候加载慢呗。其实它还有个加强版写法。
public class Men implements Person {
//第一次加载类的时候并不会实例化
private volatile static Men funky = null;
/**
* 为了只有一个男人能造出来
* 只能委屈委屈构造函数,给她private了
*/
private Men() {
}
public static Men getFunky() {
if (null == funky) {//第一次判空保证非空的时候,不走同步锁
//synchronized确保线程安全
//可能一下好几个美女需要funky我呢?
synchronized (Men.class) {
//第二次判空,万一多线程时我已经被创建了呢?
if (null == funky) {
funky = new Men();
}
}
}
return funky;
}
@Override
public void eat() {
}
}
这种算是
懒汉式的加强版。这种写法多出来一个volatile关键字,保证对象是从主内存中取出来的。刚开始看是不是感觉晕晕的。网上查了查。。实际上,创建一个对象分三步:1.分配内存 2.调用构造函数 3.指向内存,但是23两个步骤是不固定的。所以可能判断为非空的时候,对象还没构造出来了!!volatile关键字就会保证对象肯定是非空且存在的。
说了这么多,这尼玛这么复杂。还有别的单例写法吗??
答:有!上代码
public class Men implements Person {
private Men() {
}
public Men getFunky() {
return MenHolder.funky;
}
//android开发啊,对holder肯定不陌生
private static class MenHolder {
private static final Men funky = new Men();
}
@Override
public void eat() {
}
}
静态
内部类单例 ,ps:
funky我初学java的时候就觉得内部类是很帅的写法,结果走上Android这条不归路之后,各种匿名内部类写到吐2333。回到正题,这种单例写法,第一次加载的时候一样不会初始化,只有在调用get()方法的时候才会加载MenHolder这个内部类。
事实上这上面这几种就已经算是我自己所有常用的写法了(其实我只用饿汉,多容易写啊233333),网上还有很多种写法,这里就不一一举例了。