Java23种设计模式案例:单例模式(Singleton)
2016-06-26 00:00
471 查看
单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
2)灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
2)可能的开发混淆
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
3)对象生存期
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。
1、适用场景
需要使得类的一个对象成为系统运行过程中的唯一实例。2、优点
1)实例控制单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
2)灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
3、缺点
1)开销虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
2)可能的开发混淆
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
3)对象生存期
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。
4、代码示例
1)关系图
2)代码实现
实现方式1:恶汉模式
[code=language-java]//没有达到lazy loading的效果 class HungrySingleton{ private static HungrySingleton singleton=new HungrySingleton(); private HungrySingleton(){} public static HungrySingleton getInstance(){ return singleton; } }
实现方式2:懒汉模式
[code=language-java]class LazySingleton{ private static LazySingleton singleton; private LazySingleton(){ } public static LazySingleton getInstance(){ if(singleton==null){ singleton=new LazySingleton(); } return singleton; } }
实现方式3:静态内部类
[code=language-java]//加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading class InternalSingleton{ private static class SingletonHolder{ private final static InternalSingleton INSTANCE=new InternalSingleton(); } private InternalSingleton(){} public static InternalSingleton getInstance(){ return SingletonHolder.INSTANCE; } }
实现方式4:使用枚举
[code=language-java]//《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象 enum EnumSingleton{ INSTANCE; public void doSomeThing(){ } }
实现方式5:双重校验锁
[code=language-java]//带有双重校验锁的单例模式 class LockSingleton{ private volatile static LockSingleton singleton; private LockSingleton(){} public static LockSingleton getInstance(){ if(singleton==null){ synchronized(LockSingleton.class){ if(singleton==null){ singleton=new LockSingleton(); } } } return singleton; } }
实现方式6:登记式单例
[code=language-java]//类似Spring里面的方法,将类名注册,下次从里面直接获取。 class Singleton3 { private static Map<String,Singleton3> map = new HashMap<String,Singleton3>(); static{ Singleton3 single = new Singleton3(); map.put(single.getClass().getName(), single); } //保护的默认构造子 protected Singleton3(){} //静态工厂方法,返还此类惟一的实例 public static Singleton3 getInstance(String name) { if(name == null) { name = Singleton3.class.getName(); System.out.println("name == null"+"--->name="+name); } if(map.get(name) == null) { try { map.put(name, (Singleton3) Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } //一个示意性的商业方法 public String about() { return "Hello, I am RegSingleton."; } public static void main(String[] args) { Singleton3 single3 = Singleton3.getInstance(null); System.out.println(single3.about()); } }
相关文章推荐
- 举例讲解C#编程中对设计模式中的单例模式的运用
- php设计模式之单例模式实例分析
- PHP基于单例模式实现的数据库操作基类
- JavaScript编程的单例设计模讲解
- C#设计模式之单例模式实例讲解
- Javascript实现单例模式
- JS模式之单例模式基本用法
- 深入理解JavaScript系列(25):设计模式之单例模式详解
- 使用设计模式中的单例模式来实现C++的boost库
- .NET c# 单体模式(Singleton)
- Java单例模式、饥饿模式代码实例
- java设计优化之单例模式
- C# 设计模式系列教程-单例模式
- Android源码学习之单例模式应用及优点介绍
- JavaScript实现设计模式中的单例模式的一些技巧总结
- C++设计模式之单例模式
- C#窗口实现单例模式的方法
- Java线程安全中的单例模式
- PHP单例模式详细介绍
- PHP单例模式是什么 php实现单例模式的方法