设计模式初探-单例模式(Singleton)
2014-03-05 10:25
295 查看
Singleton模式,又称单例模式,它保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式在平常开发中经常用到,比如系统的全局配置属性,常用的工具类或工厂方法都可以实现为一个单例。单例模式概念很简单,实现起来也不麻烦,但一不小心还是有可能出错的。
一、使用场景
只要是要求实例唯一的都可以使用单例模式来实现,特别是耗资源的实例!
二、UML图
三、Java实现
1、懒汉型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
private static Singleton instance = null;
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
/**
* 为用户提供统一的获取类实例的接口,
* 此接口可以根据需求改变实现,即可以保持类实例的唯一,
* 也可以维持多个类实例,这对用户来说是透明的。
* @return
*/
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
通过将instance暴露为public的静态的类属性也可以实现单例模式,但较工厂方法相比缺少灵活性,比如后期单例变多例。同时,由于静态类属性是通过类加载器保证实例的唯一性(instance在类装载时才会实例化),而类装载的时机有很多种,导致对实例的创建缺乏掌控。
懒汉型单例由于延迟了类实例的创建,只在真正需要时才创建,所以较饿汉型更适用,当然如果不需要考虑实例的懒加载那就无所谓了。对于耗资源,费时间的实例创建最好采用懒汉形式实现。
2、饿汉型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
/**
* 这种方式基于classloder机制避免了多线程的同步问题,
* 不过,instance在类装载时就实例化,而导致类装载的原因有很多种。
* 在单例模式中大多数都是调用getInstance方法, 但不排除其他方式(比如调用其他的静态方法)导致类装载。
*/
private static Singleton instance = new Singleton();
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
private Singleton(){}
/**
* 为用户提供统一的获取类实例的接口,
* 此接口可以根据需求改变实现,即可以保持类实例的唯一,
* 也可以维持多个类实例,这对用户来说是透明的。
* 由于类加载器机制避免线程同步问题,所以此处不需要再同步了
* @return
*/
public static Singleton getInstance(){
return instance;
}
}
3、双重检测型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
private static Singleton instance = null;
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
/**
* 双重检测机制,确保懒加载又提高了性能。
* @return
*/
public static Singleton getInstance(){
//先判断实例是否创建好了,如果好了直接返回
if(instance == null){
//如果实例没有创建好则同步实例创建过程.
synchronized (Singleton.class) {
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}
}
双重检测机制由于将同步过程最小化,且尽可能的减少同步次数,从而提高了性能。第一种实现方式每次通过getInstance()获取实例都需要同步,而这些同步只需在实例创建时才有用,大大浪费资源。不过双重检测机制在java 5后才能表现正确的行为,参考http://www.ibm.com/developerworks/cn/java/j-dcl.html
4、枚举型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 利用java 1.5提供的枚举类型实现单例。
* 此方式较其他实现方式更简洁,由于枚举无偿地提供序列化机制,
* 绝对防止多次实例化,即使是在面向复杂的序列化或反射攻击的时候。
* 不过这种方式只能在java 1.5后使用.
* @author qbg
*/
public enum Singleton {
INSTANCE;
public void doSomething(){}
}
四、模式优缺点
优点:
1、对唯一实例的受控访问,由于Singleton类将实例的个数及产生时间都封装了起来,而不是让客户自己生成,所以它严格的控制了客户怎样及何时访问实例。
2、缩小命名空间,单例模式是对全局变量的一种改进,减少了对命名空间的污染。对于java没多大用途,java里没全局变量的概念。
3、允许可变数目的实例,这个需要实现为工厂方法,静态实例的单例模式限制只能生成1个实例。
转载于:/article/1338344.html
一、使用场景
只要是要求实例唯一的都可以使用单例模式来实现,特别是耗资源的实例!
二、UML图
三、Java实现
1、懒汉型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
private static Singleton instance = null;
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
/**
* 为用户提供统一的获取类实例的接口,
* 此接口可以根据需求改变实现,即可以保持类实例的唯一,
* 也可以维持多个类实例,这对用户来说是透明的。
* @return
*/
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
通过将instance暴露为public的静态的类属性也可以实现单例模式,但较工厂方法相比缺少灵活性,比如后期单例变多例。同时,由于静态类属性是通过类加载器保证实例的唯一性(instance在类装载时才会实例化),而类装载的时机有很多种,导致对实例的创建缺乏掌控。
懒汉型单例由于延迟了类实例的创建,只在真正需要时才创建,所以较饿汉型更适用,当然如果不需要考虑实例的懒加载那就无所谓了。对于耗资源,费时间的实例创建最好采用懒汉形式实现。
2、饿汉型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
/**
* 这种方式基于classloder机制避免了多线程的同步问题,
* 不过,instance在类装载时就实例化,而导致类装载的原因有很多种。
* 在单例模式中大多数都是调用getInstance方法, 但不排除其他方式(比如调用其他的静态方法)导致类装载。
*/
private static Singleton instance = new Singleton();
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
private Singleton(){}
/**
* 为用户提供统一的获取类实例的接口,
* 此接口可以根据需求改变实现,即可以保持类实例的唯一,
* 也可以维持多个类实例,这对用户来说是透明的。
* 由于类加载器机制避免线程同步问题,所以此处不需要再同步了
* @return
*/
public static Singleton getInstance(){
return instance;
}
}
3、双重检测型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 单例模式:根据实例创建的时机与方式可分为
* 懒汉型,饿汉型,双重检测型等
* @author qbg
*
*/
public class Singleton {
private static Singleton instance = null;
/*
* 限制客户自己生成类实例的能力,不过通过java反射机制可以突破此限制
*/
/**
* 双重检测机制,确保懒加载又提高了性能。
* @return
*/
public static Singleton getInstance(){
//先判断实例是否创建好了,如果好了直接返回
if(instance == null){
//如果实例没有创建好则同步实例创建过程.
synchronized (Singleton.class) {
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}
}
双重检测机制由于将同步过程最小化,且尽可能的减少同步次数,从而提高了性能。第一种实现方式每次通过getInstance()获取实例都需要同步,而这些同步只需在实例创建时才有用,大大浪费资源。不过双重检测机制在java 5后才能表现正确的行为,参考http://www.ibm.com/developerworks/cn/java/j-dcl.html
4、枚举型
[java] view
plaincopy
package study.patterns.singleton;
/**
* 利用java 1.5提供的枚举类型实现单例。
* 此方式较其他实现方式更简洁,由于枚举无偿地提供序列化机制,
* 绝对防止多次实例化,即使是在面向复杂的序列化或反射攻击的时候。
* 不过这种方式只能在java 1.5后使用.
* @author qbg
*/
public enum Singleton {
INSTANCE;
public void doSomething(){}
}
四、模式优缺点
优点:
1、对唯一实例的受控访问,由于Singleton类将实例的个数及产生时间都封装了起来,而不是让客户自己生成,所以它严格的控制了客户怎样及何时访问实例。
2、缩小命名空间,单例模式是对全局变量的一种改进,减少了对命名空间的污染。对于java没多大用途,java里没全局变量的概念。
3、允许可变数目的实例,这个需要实现为工厂方法,静态实例的单例模式限制只能生成1个实例。
转载于:/article/1338344.html
相关文章推荐
- 设计模式--单态(Singleton)
- 设计模式之Singleton
- 单例设计模式Singleton之懒加载模式(懒汉模式)【原】
- 设计模式之单例模式(Singleton)
- 单实例Singleton设计模式
- JAVA设计模式(03):创建型-单例模式(Singleton)
- java设计模式之单件模式Singleton
- Objective-c 单例设计模式(Singleton)
- 设计模式初探-观察者模式
- JAVA设计模式初探之装饰者模式
- Java 单例模式(singleton)类设计
- Swift辛格尔顿设计模式(SINGLETON)
- 设计模式初探-责任链模式(CHAIN OF RESPONSIBILITY)
- 设计模式单件(Singleton)---对象创建型模式
- Java学习笔记(二十四):单例设计模式singleton
- 【Unity3D与23种设计模式】单例模式(Singleton)
- 深入浅出单实例Singleton设计模式
- Java设计模式一: 单例模式(Singleton)
- 深入浅出单实例Singleton设计模式
- Java常用设计模式——单态设计模式(Singleton)