设计模式:单例模式

设计模式:单例模式

定义

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例向整个系统提供这个实例。是所有设计模式中最简单的模式。

模式分析

目的

保证一个类只有一个实例,并且提供一个访问它的全局访问点。

代码实现

public class Singleton {
    //静态私有成员变量
    private static Singleton instance;
    //私有构造函数
    private Singleton(){}
    //静态公有工厂方法,返回唯一的实例
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

在Singleton类中,成员变量和构造方法是私有的,外界类不能通过构造方法实例化Singleton对象(不能通过new来常见对象),getInstance()方法是静态公有的,外界类可以直接通过类名(Singleton)调用getInstance()方法。

getInstance()方法先判断instence是否为空,当instance == null 时才创建Singleton对象,否则直接返回静态变量instence,也就是说,只有Singleton对象被第一次创建时,才满足if条件,保证了类只有一个实例。getInstance()方法返回一个Singleton对象,是外界类获取Singleton对象的唯一方法,所以getInstance()方法是Singleton类提供的访问它的全局访问点

优点

  1. 提供了唯一实例的受控访问。单例类可以严格可能控制客户何时以及怎样访问它。
  2. 节约系统资源。只有一个实例,节约资源,对于一些需要频繁创建和销毁的对象,单例模式可以提高系统的性能。
  3. 允许可变数目的实例。可以进行扩展,使用相似的方法指定对象实例的个数。

缺点

  1. 扩展困难。只有一个类,没有抽象层。
  2. 可能会造成资源无法及时释放。单例模式使用静态成员变量存储类的实例。(例如数据库的连接,需要及时释放资源)。

举例

在实际中,一台打印机可以连接多台设备,但是打印机在某一段时间只能完成一项打印任务。

public class Print {
    //静态私有成员变量
    private static Print instance = null;
    //私有构造函数

    public Print() {
    }

    //静态公有工厂方法,返回唯一的实例
    public static Print getInstance(){
        if(instance == null){
            System.out.println("连接打印机");
            instance = new Print();
        }else{
            System.out.println("打印机正在工作");
        }
        return instance;
    }

}
public class Client {
    public static void main(String[] args) {
        Print p1,p2;
        p1 = Print.getInstance();
        System.out.println("--------------");
        p2 = Print.getInstance();
    }
}

在这里插入图片描述

在客户端测试代码中定义了两个打印任务,通过getInstance()两次获取对象实例,第二次时输出“打印机正在工作”,说明和第一次使用的是同一台打印机,所以打印机对象只被实例化了一次。

扩展

饿汉式单例

在初始化静态变量时创建对象,将变量设为static final(不可变),是JAVA语言中实现起来最方便的单例类。

private static final Singleton instance = new Singleton();
    //私有构造函数
    private Singleton(){}
    //静态公有工厂方法,返回唯一的实例
    public static Singleton getInstance(){
        return instance;
    }

在这个类被加载时,加载静态变量和静态方法,此时instance会被初始化,单例类的唯一实例被创建。

懒汉式单例

当第一次被引用时才创建实例。

//静态私有成员变量
    private static Singleton instance =null;
    //私有构造函数
    private Singleton(){}
    //静态公有工厂方法,返回唯一的实例
    synchronized public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }

使用了同步化机制(synchronized),用来处理多线程环境。

实践

编写Triple类,实现最多只能生成3个实例,实力编号分别为0,1,2,且可以通过getInstence(int id)来获取该编号的实例。

public class Triple {
    private static Triple[] triple = new Triple[]{
        new Triple(0),
        new Triple(1),
        new Triple(2),
    };
    private int id;
    private Triple(int id) {                                 
        System.out.println("The instance " + id + " is created.");
        this.id = id;
    }
    public static Triple getInstance(int id) {
        return triple[id];
    }
    public String toString() {
        return "[Triple id=" + id + "]";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值