单例模式的定义
确保某个类只有一个实例,且自行实例化向外提供
使用场景
当一个对象需要频繁的创建销毁的时候
当一个对象需要较多资源的时候
...
UML类图
实现方式
1.饿汉模式
并初始化一个私有的静态成员变量
写私有构造函数
公有的静态函数暴露对外的单例接口
eg:
```
public class Singleton{
private static final Singleton mSingleton = new Singleton();
private Singleton() {
}
public static Singleton getSingleton() {
return mSingleton;
}
}
```
2.懒汉模式
声明一个私有的静态成员变量
写私有的构造函数
在用户第一次调用的时候初始化
eg:
```
public class Singleton{
private static Singleton mSingleton;
private Singleton() {
}
public static synchronized Singleton getSingleton() {
if (mSingleton == null) {
mSingleton = new Singleton;
}
return mSingleton;
}
}
```
3.Double Lack Check(DLC)
public class Singleton {
public static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
if (mSingleton == null) {
sunchronized(Singleton.class) {
if (mSingleton == null) {
mSingleton = new Singleton();
}
}
}
}
}
4.静态内部类
public class Singleton {
private Singleton() { }
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
5.枚举
public enum SingletonEnum {
INSTANCE;
//methdo
}
6.容器实现
public class Singleton {
private Static Map objMap = bew HasMap();
private Singleton() {}
public static void registerSingleton (String key, Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key, instaance);
}
}
public static Object getSingleton(String key) {
return objMap.get(key);
}
}
在android中的使用
1.getSystemService中使用的单例模式
在我们编写android程序时经常会使用Context的getSystemService(String key)方法来获取系统权限我们可以进去Context类来查看下这个方法
public abstract Object getSystemService(@ServiceName @NonNull String name);
这是一个抽象方法我们需要去看该方法的实现ContextImpl中的getSystemService()方法
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
在这个方法里调用了SystemServiceRegistry类getSystemService()方法
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
是不是很熟悉这个方法?是不是跟我们单例模式的第六种实现方式容器实现有点类似下面我们就详细看下SystemServiceRegistry类的结构
final class SystemServiceRegistry {
private final static String TAG = "SystemServiceRegistry";
// Service registry information.
// This information is never changed once static initialization has completed.
private static final HashMap, String> SYSTEM_SERVICE_NAMES =
new HashMap, String>();
private static final HashMap> SYSTEM_SERVICE_FETCHERS =
new HashMap>();
private static int sServiceCacheSize;
// Not instantiable.
private SystemServiceRegistry() { }
static {
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class,
new CachedServiceFetcher() {
@Override
public CaptioningManager createService(ContextImpl ctx) {
return new CaptioningManager(ctx);
}});
//由于篇幅这里省略了一些代码,有兴趣的同学可以自己去看
private static void registerService(String serviceName, Class serviceClass,
ServiceFetcher serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
}
看到这里我相信大家就明白了吧,这就是我们之前的单例模式的第六种写法的实现