单例模式,指的是程序在运行过程中,只产生一个实例对象。
实现单例的目的,是为了在程序运行中只产生一个实例,从而节约资源,提高效率。产生的这唯一的实例对象一定有相关的业务操作,制造出单例对象是为一定的目的服务的。
实现单例模式有4个步骤:
- 静态私有属性
- 私有构造方法
- 公有的静态的获取实例的方法
- 公有的业务方法
举例说明:
public class Singleton {
//1、私有静态变量
private static Singleton singleton;
private Person person;//业务对象
//2、私有构造方法
private Singleton(){
person = new Person();
}
//3、公有静态方法,获取实例对象
//加上同步锁 synchronized,线程安全
public static synchronized Singleton getInstance(){
if(null == singleton){
singleton = new Singleton();
}
return singleton;
}
//4、公有业务方法
public String getPersonName(){
return person.getName();
}
}
单例对象在什么时候使用呢,比如:这有一个 selectCode.xml 文件,里面是方位和省份的信息,这些信息是固定的,我的程序可能在很多个地方要使用这些定位的信息,那么,每使用一次就 new 一个对象读取一次肯定不是个好方法;此时,使用单例模式,在整个程序运行中,只创建了一个对象,使用时直接获取即可。
<?xml version="1.0" encoding="utf-8"?>
<selectcode>
<code name="position" description="方位">
<parameter key="1" value="华北"/>
<parameter key="2" value="东北"/>
<parameter key="3" value="华东"/>
<parameter key="4" value="中南"/>
<parameter key="5" value="西南"/>
<parameter key="6" value="西北"/>
</code>
<code name="district" description="省份">
<parameter key="11" value="北京"/>
<parameter key="12" value="天津"/>
<parameter key="13" value="河北省"/>
<parameter key="14" value="山西省"/>
<parameter key="15" value="内蒙古"/>
<parameter key="21" value="辽宁省"/>
<parameter key="22" value="吉林省"/>
<parameter key="23" value="黑龙江"/>
<parameter key="31" value="上海"/>
<parameter key="32" value="江苏省"/>
<parameter key="33" value="浙江省"/>
<parameter key="34" value="安徽省"/>
<parameter key="35" value="福建省"/>
<parameter key="36" value="江西省"/>
<parameter key="37" value="山东省"/>
<parameter key="41" value="河南省"/>
<parameter key="42" value="湖北省"/>
<parameter key="43" value="湖南省"/>
<parameter key="44" value="广东省"/>
<parameter key="45" value="广西省"/>
<parameter key="46" value="海南省"/>
<parameter key="50" value="重庆"/>
<parameter key="51" value="四川省"/>
<parameter key="52" value="贵州省"/>
<parameter key="53" value="云南省"/>
<parameter key="54" value="西藏"/>
<parameter key="61" value="陕西省"/>
<parameter key="62" value="甘肃省"/>
<parameter key="63" value="青海省"/>
<parameter key="64" value="宁夏省"/>
<parameter key="65" value="新疆"/>
</code>
</selectcode>
//使用单例模式,读取两个节点的xml文件,实例化唯一一个选择区域的对象Map
//使用 dom4j 读取 xml
public class SelectCodeUtil {
//1、私有静态变量
private static SelectCodeUtil selectCodeUtil;
private Map<String,List<Parameter>> selectMap;//业务对象
private Document document;
//2、私有构造方法
private SelectCodeUtil(String filePath){
List<Parameter> listPosition = new ArrayList<Parameter>();
List<Parameter> listDistrict = new ArrayList<Parameter>();
selectMap = new HashMap<String, List<Parameter>>();
try {
//载入文件
SAXReader saxReader = new SAXReader();
document = saxReader.read(new File(filePath));
//获取根节点
Element root = document.getRootElement();
Iterator<Element> eleBrands = root.elementIterator();
//读取节点
while(eleBrands.hasNext()){
Element brand = (Element)eleBrands.next();
String key = brand.attributeValue("name");
if(key.equals("position")){
Iterator<Element> eleTypes = brand.elementIterator();
while(eleTypes.hasNext()){
Element type = (Element)eleTypes.next();
Parameter parameter = new Parameter(type.attributeValue("key"), type.attributeValue("value"));
listPosition.add(parameter);
}
//把取到的值放进Map
selectMap.put(key, listPosition);
}
if(key.equals("district")){
Iterator<Element> eleTypes = brand.elementIterator();
while(eleTypes.hasNext()){
Element type = (Element)eleTypes.next();
Parameter parameter = new Parameter(type.attributeValue("key"), type.attributeValue("value"));
listDistrict.add(parameter);
}
//把取到的值放进Map
selectMap.put(key, listDistrict);
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
//3、公有静态方法,获取实例对象
public static synchronized SelectCodeUtil getInstance(String filePath){
if(null == selectCodeUtil){
selectCodeUtil = new SelectCodeUtil(filePath);
}
return selectCodeUtil;
}
//4、公有业务方法
public Map<String, List<Parameter>> getSelectMap(){
return selectMap;
}
//测试
public static void main(String[] args) {
//xml文件绝对路径
String filePath = new File("src/main/resources/SelectCode.xml").getAbsolutePath();
Map<String, List<Parameter>> map = SelectCodeUtil.getInstance(filePath).getSelectMap();
//遍历输出
Set<String> keys = map.keySet();
for(String key : keys){
System.out.println("节点 "+key);
List<Parameter> list = (List<Parameter>)map.get(key);
for(Parameter p:list){
System.out.println("\t"+p.getKey()+"\t"+p.getValue());
}
}
}
}
运行结果:
节点 district
11 北京
12 天津
13 河北省
14 山西省
15 内蒙古
21 辽宁省
22 吉林省
23 黑龙江
31 上海
32 江苏省
33 浙江省
34 安徽省
35 福建省
36 江西省
37 山东省
41 河南省
42 湖北省
43 湖南省
44 广东省
45 广西省
46 海南省
50 重庆
51 四川省
52 贵州省
53 云南省
54 西藏
61 陕西省
62 甘肃省
63 青海省
64 宁夏省
65 新疆
节点 position
1 华北
2 东北
3 华东
4 中南
5 西南
6 西北
成功取出 map 里的值,这样,在程序的其他地方用到时,只需要 SelectCodeUtil.getInstance(filePath).getSelectMap();
就可以了。