适用情况:系统只需要一个实例对象。客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。如Windows操作系统中的任务管理器。试想,如果有多个窗口都打开着任务管理器,那么这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真正的状态。
使用单例模式有个必要条件:在一个系统中要求一个类只有一个实例时才应当使用单例模式。反过来,如果一个类可以有几个实例共存,这就需要对单例模式进行改进,使之成为多例模式。
定义:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实力,这个类称为单例类,它提供全局访问的方法。单例模式有三个要点:一是某一个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
模式结构图:
代码(理解static修饰符的作用):
客户端:
package com.singletonpattern.hing; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub IDCard instance = IDCard.getInstance(); IDCard instance1 = IDCard.getInstance(); System.out.println(instance == instance1); IDCard instance2 = IDCard.getInstance(); System.out.println(instance2.getIdNmuber()); } }
单例类:
package com.singletonpattern.hing; public class IDCard { private String idNmuber; public String getIdNmuber() { return idNmuber; } public void setIdNmuber(String idNmuber) { this.idNmuber = idNmuber; } private static IDCard instance = null; private IDCard() { } public static IDCard getInstance() { if(instance == null) { instance = new IDCard(); instance.idNmuber = "51822199701224812"; return instance; }else { return instance; } } }
补充:
饿汉式单例类:
调用getInstance之前就生成了单例类
//饿汉式单例类 public class EagerSingleton{ private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } }
懒汉式单例类:
调用getInstance时再创建单例对象
//懒汉式单例类 public class LazySingleton{ private static LazySingleton instance = null; private LazySingleton() { } public LazySingleton getInstance() { if(instance == null) { return new LazySingleton(); }else { return instance; } } }
总结:总的来讲,单例模式相对比较简单,对于JAVA而言,主要是利用好关键字static、final等,通过使用类名.方法的方式来获取单例,以达到唯一的效果