最近在研究设计模式, 先从最简单的单例模式开始吧
因为在实际开发中, 很多地方在对象的实例化方面需要做一个全局的对象来操作某些特别的资源
比如: thread Pool, cach, SDK中的选项设置页, log 等等
在整个软件中他们其实只需要一个实例就可以了, 如果做到只有一个实例呢
下面我以java为例, 来讲一下单个实例的实现
首先在java中创建一个实例是用 new MyClass()来实现的
java类的构造函数默认是public的, 意味着很多都可以来创建此类的实例
如果做到只有一个实例呢, 答案是我们来控制new的方式,
在java把构造函数设置为private即可, 比如
public MyClass{
private MyClass(){}
}
但是这样一来我们如何实例化类呢,
public MyClass {
private MyClass() {}
public static MyClass getInstance() {
return new MyClass();
}
}
这样我们就可以通过getInstance方法来实例化我们的类, 我们通过方法来控制这个类的实例化
但是这样每次调用getInstance()都创建了MyClass, 其实我们只想创建一个即可
这时我们需要再加入一个静态变量, 变量的作用用来存储类的实例
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
} //
这样我们就可以看到第一次创建的时候判断一下是否存在实例, 不存在就创建,
但是在多线程程序中, 很可能被两个以上的线程同时访问到getInstance()函数, 这时候同时判断实例为null 并同时进去
还好在java中有机制来保证线程的并发, synchronized 关键字, 上面的程序改写如下
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;}
但是还有人说, 每次访问getInstance都要去判断一下, 其实作用就在第一次创建实例, 后面其实用不到了
其实这根据你的实例的大小, 如果整个实例本来很大, 创建后会占用资源, 建议采用上面的方式创建
如果不想每次都判断, 在类加载的时候就可以实例化了, 代码如下
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
}