单例模式,应该是应用最广泛的一个设计者模式,也是我在众多模式中第一个接触到的一个模式。
为什么需要单例模式?
在许多时候整个系统只需要一个全局对象,这样有利于我们协调系统整体的行为,像应用中的用OKhttp去做网络请求,一般网络请求会有线程池,缓存系统,网络请求等,很消耗资源 ,因此 没有理由让它构造多个实例,这种不能自由构造对象的情况就是单例模式。
定义:
确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
使用场景:
确保某个类只有一个对象,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个,例如:访问IO和数据库等资源。
单例模式的几个关键点:
1.构造函数不对外开放,一般为private。
2.通过一个静态或枚举放回单例类的对象.
3.确保单例类的对象有且只有一个,尤其在多线程的情况下。
4。确保单例类对象在反序列化时不会重写构建对象。
用过构造函数私有化,使得不能以 new 的形式构造单例类的对象,单例类会暴露一个公有静态方法,使得要调用这个静态的方法才能获取单例类的对象。
单例模式实现方式:
实现单例模式的方式有很多种,这里只写推荐使用的静态内部类单例模式实现,这里以网络(Rxjava+Retrofit+Okhttp)请求为例
public class HttpUtil {
private static final String BASE_URL = "http://www.wanandroid.com/";
private static final int TIMEOUT = 10;
private Retrofit retrofit;
private HttpInerface httpInerface;
//构造方法私有化
private HttpUtil() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new ReceivedCookiesInterceptor())
.addInterceptor(new AddCookiesInterceptor())
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
httpInerface = retrofit.create(HttpInerface.class);
}
private static class sinalInstance {
private static final HttpUtil instance = new HttpUtil();
}
//通过公有的静态方法返回单例类的对象
public static HttpUtil getInstance() {
return sinalInstance.instance;
}
}
静态内部类单例模式的好处是,第一次加载 HttpUtil时不会初始化,单例类的对象,只有第一次调用的时候才会调用HttpUtil 的 getInstance() 方法,这样不仅能确保线程安全,也能保证单例类对象的唯一性,同时也也延迟了单例的实例化。
其他的单例模式的实现方式,就不一一实现了,选择哪种都是取决于项目的本身,。