Android死磕之旅Android开发Android开发

Android的设计模式-单例模式

2017-10-18  本文已影响620人  四月葡萄

前言

Android的设计模式系列文章介绍:欢迎关注,持续更新中:

Android的设计模式-设计模式的六大原则
一句话总结23种设计模式则
创建型模式:
Android的设计模式-单例模式
Android的设计模式-建造者模式
Android的设计模式-工厂方法模式
Android的设计模式-简单工厂模式
Android的设计模式-抽象工厂模式
Android的设计模式-原型模式
行为型模式:
Android的设计模式-策略模式
Android的设计模式-状态模式
Android的设计模式-责任链模式
Android的设计模式-观察者模式
Android的设计模式-模板方法模式
Android的设计模式-迭代器模式
Android的设计模式-备忘录模式
Android的设计模式-访问者模式
Android的设计模式-中介者模式
Android的设计模式-解释器模式
Android的设计模式-命令模式
结构型模式:
Android的设计模式-代理模式
Android的设计模式-组合模式
Android的设计模式-适配器模式
Android的设计模式-装饰者模式
Android的设计模式-享元模式
Android的设计模式-外观模式
Android的设计模式-桥接模式

1.定义

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

2.介绍

单例模式属于创建类模式。
单例模式有以下特点:

 1. 单例类只能有一个实例。
 2. 单例类必须自己创建自己的唯一实例。
 3. 单例类必须给所有其他对象提供这一实例。

3.实现

3.4 饿汉式
//单例类.   
public class Singleton {
    
    private Singleton() {//构造方法为private,防止外部代码直接通过new来构造多个对象
    }

    private static final Singleton single = new Singleton();  //在类初始化时,已经自行实例化,所以是线程安全的。

    public static Singleton getInstance() {  //通过getInstance()方法获取实例对象
        return single;
    }
}  
3.1 懒汉式(线程不安全)
//单例类
public class Singleton {
    private Singleton() {
    }

    private static Singleton single = null;

    public static Singleton getInstance() {
        if (single == null) {
            single = new Singleton();  //在第一次调用getInstance()时才实例化,实现懒加载,所以叫懒汉式
        }
        return single;
    }
} 
3.1 懒汉式(线程安全)
//单例类
public class Singleton {
    private Singleton() {
    }

    private static Singleton single = null;

    public static synchronized Singleton getInstance() { //加上synchronized同步 
        if (single == null) {
            single = new Singleton();
        }
        return single;
    }
}  
3.3 双重检查锁定(DCL)
public class Singleton {
    private volatile static Singleton singleton; //volatile 能够防止代码的重排序,保证得到的对象是初始化过

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) {  //第一次检查,避免不必要的同步
            synchronized (Singleton.class) {  //同步
                if (singleton == null) {   //第二次检查,为null时才创建实例
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
} 
3.5 静态内部类
public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        //第一次调用getInstance方法时才加载SingletonHolder并初始化sInstance
        return SingletonHolder.sInstance;
    }
    
    //静态内部类
    private static class SingletonHolder {
        private static final Singleton sInstance = new Singleton();
    }
}
3.6 枚举单例
public enum Singleton {

    INSTANCE;   //定义一个枚举的元素,它就是Singleton的一个实例

    public void doSomething() {
    }
}  
3.7 使用容器实现单例模式
//单例管理类
public class SingletonManager {
    private static Map<String, Object> objMap = new HashMap<String, Object>();

    public static void registerService(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);//添加单例
        }
    }

    public static Object getService(String key) {
        return objMap.get(key);//获取单例
    }
}

4.注意事项

  1. 使用反射能够破坏单例模式,所以应该慎用反射
    Constructor con = Singleton.class.getDeclaredConstructor();
    con.setAccessible(true);
    // 通过反射获取实例
    Singleton singeton1 = (Singleton) con.newInstance();
    Singleton singeton2 = (Singleton) con.newInstance();
    System.out.println(singeton1==singeton2);//结果为false,singeton1和singeton2将是两个不同的实例
public class Singleton {
    private static boolean flag = true;
    private static Singleton single = null;

    private Singleton() {
        if (flag) {
            flag = !flag;
        } else {
            throw new RuntimeException("单例模式被破坏!");
        }
    }

    public static Singleton getInstance() {
        if (single == null) {
            single = new Singleton();
        }
        return single;
    }
}  
  1. 反序列化时也会破坏单例模式,可以通过重写readResolve方法避免,以饿汉式为例:
public class Singleton implements Serializable {
    private Singleton() {
    }

    private static final Singleton single = new Singleton();

    public static Singleton getInstance() {
        return single;
    }

    private Object readResolve() throws ObjectStreamException {//重写readResolve()
        return single;//直接返回单例对象
    }
} 

5.应用场景

6.优点

7.缺点

相关文章阅读
Android的设计模式-设计模式的六大原则
一句话总结23种设计模式则
创建型模式:
Android的设计模式-单例模式
Android的设计模式-建造者模式
Android的设计模式-工厂方法模式
Android的设计模式-简单工厂模式
Android的设计模式-抽象工厂模式
Android的设计模式-原型模式
行为型模式:
Android的设计模式-策略模式
Android的设计模式-状态模式
Android的设计模式-责任链模式
Android的设计模式-观察者模式
Android的设计模式-模板方法模式
Android的设计模式-迭代器模式
Android的设计模式-备忘录模式
Android的设计模式-访问者模式
Android的设计模式-中介者模式
Android的设计模式-解释器模式
Android的设计模式-命令模式
结构型模式:
Android的设计模式-代理模式
Android的设计模式-组合模式
Android的设计模式-适配器模式
Android的设计模式-装饰者模式
Android的设计模式-享元模式
Android的设计模式-外观模式
Android的设计模式-桥接模式

上一篇 下一篇

猜你喜欢

热点阅读