单例模式,顾名思义就是程序在运行的过程中,有且只有一个实例。它必须满足三个关键点。
1)一个类只有一个实例。这是满足单例模式最基本的要求,若要满足这个关键点,只能提供私有的构造器,即保证不能随意创建该类的实例。
public class ConfigManager {
private static ConfigManager configManager;
//私有构造器-读取数据库配置文件
private ConfigManager(){
String configFile = "database.properties";
properties = new Properties();
InputStream is =
ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
try {
properties.load(is);
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在上述代码中,我们把读取配置文件的I/O操作代码放入私有构造器里,这样可以有效地保证I/O操作在整个系统运行期间仅被执行一次,以解决资源消耗问题。
2)它必须自行创建这个实例。对于这一点,正是体现了:单例模式的“有且仅有一个实例”的这一特性。我们要保证唯一性,也就意味着必须要提供一个实例,那么就需要它自行创建,定义一个ConfigManager类型的静态的私有对象,以便向外界提供该类实例时使用。
//读取配置文件的工具类-单例模式
public class ConfigManager {
private static ConfigManager configManager;
private static Properties properties;
//私有构造器-读取数据库配置文件
private ConfigManager(){
String configFile = "database.properties";
properties = new Properties();
InputStream is =
ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
try {
properties.load(is);
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在上面的代码中,我们定义了一个ConfigManager的静态私有对象configManager。
3)它必须自行向整个系统提供这个实例。最后一点也是至关重要的,外界需要获取并使用这个单例类的实例,但是由于该类的构造器是私有的,外界无法通过new去获取它的实例,那么就必须提供一个静态的公有方法,该方法创建或者获取它本身的静态私有对象并返回。
//读取配置文件的工具类-单例模式
public class ConfigManager {
private static ConfigManager configManager;
private static Properties properties;
//私有构造器-读取数据库配置文件
private ConfigManager(){
String configFile = "database.properties";
properties = new Properties();
InputStream is =
ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
try {
properties.load(is);
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//全局访问点
public static ConfigManager getInstance(){
if(configManager == null){
configManager = new ConfigManager();
}
return configManager;
}
//根据传入的key获取相应的value值
public String getValue(String key){
return properties.getProperty(key);
}
}
在上面的代码中,我们添加了一个全局的访问点getInstance()方法,该方法返回该类的实例,以被外界使用。在该方法体内,进行了简单的逻辑判断,若configManager为null,那么创建该实例;若不为空,那么直接返回configManager实例即可,不需要再实例化该类的对象。
为什么要将getInstance()方法定位为static呢?
因为作为该单例类的全局访问点,外界需要哦调用该方法来获取configManager方法,则该方法必须也是静态的,否则无法调用。