问题场景:为了系统的可维护性,如今系统中都会有一些配置文件,而这些配置文件需要做一些初始化,一般来说,配置文件都是以xml或者properties文件形式存在,今天以properties来重现问题传统的来说,我们会创建一个和配置文件属性相关的配置类.ConfigModel。有一个解析配置文件的地方,将配置文件内容存到ConfigModel的实例当中,由于系统中用到配置文件的地方可能会很多,这样就会有多个ConfigModel的实例存在内存中,他们的内容又是一样,于是这时就造成了资源的浪费。
问题重现:
配置文件:config.properties的内容
1=this is a test
2=what do you know
ConfigModel类
写本类需要注意的是,在读取结束的时候要关闭流。
如此可以直接在Client类中调用:
想想有什么问题?
明显的,是调用中有new关键字,这个字是为产生新对象则存在的,在我们系统内有多个地方需要配置文件的内容的时候,我们就会新创建一个对象放到内存里,这样该造成多大的资源浪费啊...
我们可以就只创建一个对象,同一个对象,在用的时候去取不就完了吗?
于是就有了singleton,单例
单例模式有两种写法,我分别介绍.
1、懒汉式
重写ConfigModel1
问题重现:
配置文件:config.properties的内容
1=this is a test
2=what do you know
ConfigModel类
/**
* 配置文件
* @author liuwy
*
*/
public class ConfigModel {
private String paramA;
private String paramB;
public String getParamA() {
return paramA;
}
public void setParamA(String paramA) {
this.paramA = paramA;
}
public String getParamB() {
return paramB;
}
public void setParamB(String paramB) {
this.paramB = paramB;
}
public ConfigModel() {
config();
}
private void config() {
Properties prop = new Properties();
InputStream in = null;
try {
in = ConfigModel.class.getResourceAsStream("config.properties");
prop.load(in);
this.paramA = prop.getProperty("1");
this.paramB = prop.getProperty("2");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
写本类需要注意的是,在读取结束的时候要关闭流。
如此可以直接在Client类中调用:
public static void main(String[] args) {
ConfigModel m = new ConfigModel();
System.out.println(m.getParamA());
System.out.println(m.getParamB());
}
明显的,是调用中有new关键字,这个字是为产生新对象则存在的,在我们系统内有多个地方需要配置文件的内容的时候,我们就会新创建一个对象放到内存里,这样该造成多大的资源浪费啊...
我们可以就只创建一个对象,同一个对象,在用的时候去取不就完了吗?
于是就有了singleton,单例
单例模式有两种写法,我分别介绍.
1、懒汉式
重写ConfigModel1
/**
* 懒汉式
* @author liuwy
*
*/
public class ConfigModel1 {
private String paramA;
private String paramB;
public String getParamA() {
return paramA;
}
public void setParamA(String paramA) {
this.paramA = paramA;
}
public String getParamB() {
return paramB;
}
public void setParamB(String paramB) {
this.paramB = paramB;
}
private static ConfigModel1 m = null;
//私有化构造方法
private ConfigModel1() {
config();
}
public static ConfigModel1 getInstance() {
if(m == null) {
m = new ConfigModel1();
return m;
}
return m;
}
private void config() {
Properties prop = new Properties();
InputStream in = null;
try {
in = ConfigModel.class.getResourceAsStream("config.properties");
prop.load(in);
this.paramA = prop.getProperty("1");
this.paramB = prop.getProperty("2");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端中只需要ConfigModel1.getInstatnce()调用产生m就行了。
由程序中可以看到,我们只是在内存中滑configModel的时候才去创建,有的话就返回,即保证了内存中只有一个config,节省了空间。
2、饿汉式:
与懒汉式稍有不同,只是在定义ConfieModel1的时候,直接new初始化
getInstance() 中直接返回对象
这样的做法是系统直接在内存中存在了一个对象,而且是一直存在,不需要客户再去创建,节省了时间。
可以分析得出:懒汉式是以时间换空间,而饿汉式则是以空间换时间。
由程序中可以看到,我们只是在内存中滑configModel的时候才去创建,有的话就返回,即保证了内存中只有一个config,节省了空间。
2、饿汉式:
与懒汉式稍有不同,只是在定义ConfieModel1的时候,直接new初始化
getInstance() 中直接返回对象
这样的做法是系统直接在内存中存在了一个对象,而且是一直存在,不需要客户再去创建,节省了时间。
可以分析得出:懒汉式是以时间换空间,而饿汉式则是以空间换时间。