JAVA设计模式之单例模式

1.1 单例模式介绍

     单例模式是我们最常用的一种模式之一 , 当然对于初级的工程师可能是唯一会使用的设计模式 , 最近越来越发现设计模式是多么的重要 , 所以最近就专攻 <<设计模式>> 这个大山 , 首先我们先从最简单的来开始吧 !


1.2 单例模式的定义

      Ensure a class has only one instance, and provide a global point of access to it.

      (确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)


1.2.1单例模式的缺点

  单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。单例模式为什么不能增加接口呢?

  因为接口对单例模式是没有任何意义的,它要求“自行实例化”,并且提供单一实例、接口或抽象类是不可能被实例化的。

  当然,在特殊情况下,单例模式可以实现接口、被继承等,需要在系统开发中根据环境判断。
  单例模式对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行
  测试的,没有接口也不能使用mock的方式虚拟一个对象。
  单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,  单例模式把  “要单例”和业务逻辑融合在一个类中。


1.2.2单例模式的使用场景

  在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式,具体的场景如下:
  ● 要求生成唯一序列号的环境;
  ● 在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
  ● 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
  ● 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当
然,也可以直接声明为static的方式)。


1.3 单例模式关键点

      (1) 构建函数权限不对外开放 , 一般为Private

       (2) 通过公共静态方法返回单例对象

       (3) 确保只有一个实例 , 尤其是在多线程下


1.4 单例模式代码示例

      单例模式一般分为两个模式: (1) 饿汉式  (2) 懒汉式

      1.4.1 懒汉式

私有化构造函数和实例初始化,对外界提供一个静态方法判空并提供实例对象,保证只有一个实例

package com.example.liangshaoteng.imageloader;

/**
 * Created by liangshaoteng on 17-6-26.
 */

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

      1.4.2 饿汉式

实例化一个私有的实例对象通过静态方法返回给使用者,保证只有一个实例

package com.example.liangshaoteng.imageloader;

/**
 * Created by liangshaoteng on 17-6-26.
 */

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return singleton;
    }
}

1.5 单例模式的其他实现方式

      1.5.1 懒汉式

下面这个大家会发现多出一个synchronized方法这个就是我们之前说的确保一个实例尤其实在多线程下,我们可以通过synchronized方法进行同步,来保证唯一实例对象

package com.example.liangshaoteng.imageloader;

/**
 * Created by liangshaoteng on 17-6-26.
 */

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

      1.5.2 Double Check Lock (DCL)实现实例

大家在看的过程中会发现有两个判空,为什么呢? 这是因为如果我们不加第一个判断的话每使用一次都将进行同步,这样会消耗不必要的资源 , 这也是懒汉式存在最大的问题

package com.example.liangshaoteng.imageloader;

/**
 * Created by liangshaoteng on 17-6-26.
 */

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

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

      1.5.3 静态内部类单例实现

下面这个当我们加载Singleton的时候并不会实例化,只有在调用getInstance方法才会导致single被初始化

package com.example.liangshaoteng.imageloader;

/**
 * Created by liangshaoteng on 17-6-26.
 */

public class Singleton {

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingleHolder.single;
    }

    private static class SingleHolder {
        private static final Singleton single = new Singleton();
    }
}

      1.5.4 枚举

package com.example.liangshaoteng.imageloader;

import static com.example.liangshaoteng.imageloader.single.SINGLE;

/**
 * Created by liangshaoteng on 17-6-26.
 */

enum single{
    SINGLE;
    
    public void doSomething(){
        
    }
}




 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值