深入浅出设计模式——从球赛中悟单例模式

一、单例模式概念

    单例模式属于最简单的设计模式之一,简单的说就是保证一个类只有一个对象实例的设计模式。

    放在足球比赛中就好比一支球队只有一个主教练,那么主教练就是单例的。

二、使用场景

    同一个对象被反复的创建并且创建这个对象的消耗的资源很多的情况下就可以使用单例模式(要找到一个合适主教练是很难的,我们不能每次要用到主教练的时候就重新找一个吧)。

三、结构

    单例模式的结构相当简单,其实就是一个单例类,所以也就不需要UML图来表示了,直接开始撸代码。

四、实现

    单例模式又多种不同的实现方式,我就选择我们最常用的两种:饿汉式和懒汉式来说明吧。

1. 饿汉式单例模式

public class Coach1 {

    private static final Coach1 coach = new Coach1();
    private Coach1(){}

    public static Coach1 getInstance(){
        return coach;
    }

}

    这个一号教练比较着急,从一开始就站在场边随时准备指挥场上球员。这样做的优点是线程安全,并且执行效率高,因为一开始就时刻准备着。缺点也很明显,浪费体力,反映在项目里就是耗内存。

2.懒汉式单例模式

public class Coach2 {
    private static Coach2 coach;
    private Coach2(){}

    public static Coach2 getInstance(){
        if (coach == null) {
            coach = new Coach2();
        }
        return coach;
    }
}

    这个二号教练就比较懒了,再没有人叫他的时候他是不会工作的,只有在有人叫他了的情况下,也就是调用getInstance的情况下他才会开始工作。但是细心的读者会发现,如果两个人同时叫他,当走到判断是否为空的时候有可能两个人得到的结果都是空,这样就有可能叫来两个教练。下面我们针对这个问题进行改进,改进的方法当然是——同步。

public class Coach2 {
    private static Coach2 coach;
    private Coach2(){}

    public synchronized static Coach2 getInstance(){
        if (coach == null) {
            coach = new Coach2();
        }
        return coach;
    }
}

    完成,但是问题又来了,如果这时候有多个人一起来叫,不过教练在不在,大家都得排队一个一个来。效率很低对不对,那么我们继续改进。

public class Coach2 {
    private static Coach2 coach;
    private Coach2(){}

    public  static Coach2 getInstance(){
        if (coach == null) {
            synchronized (Coach2.class) {
                if (coach == null) {
                    coach = new Coach2();
                }
            }
        }
        return coach;
    }
}

    这下好了,只要在教练不在的时候我们去叫他才会出现排队的情况,如果教练就在那儿,不过多少人,来叫就行了,效率也高了不少。

    当然了,单例模式还有一些其他的实现方式,由于平时都很少用到,我这里就不一一列举了。

五、优势

     由于单例在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。

六、局限性

    没有接口,不能继承。并且对于单例类来说它既要关心内部逻辑有需要考虑要外部如何来实例化它,这也就违背了单一职责原则。当然了,世界上没有十全十美的模式,每个设计模式都有它适用的地方,只要我们的使用方式得当,那么单例模式可以帮助我们写出漂亮优雅的代码。

附源码地址:https://gitee.com/jack90john/singleton

------------------------------------------------------------------------

欢迎关注我的个人公众号,推送最新文章

猜你喜欢

转载自my.oschina.net/jack90john/blog/1794014