Re:Android 设计模式-单例

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),网上还有很多种写法,这里就不一一举例了。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值