设计模式之二 --- Singleton 模式

【1】基本概念

       Singleton 是一种创建性模式,它用来确保只产生一个实例,并提供一个访问它的全局访问点。对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在。

【2】简单分析

        我们先来看一下该设计模式的UML结构图:


为了实现 Singleton 模式,我们需要的是一个静态的变量,能够在不创建对象的情况下记忆是否已经产生过实例了。静态变量或静态方法都可以在不产生具体实例的情况下直接调用,这样的变量或方法不会因为类的实例化而有所改变。在上面的模式结构图中的 uniqueInstance 就是这个独立的静态变量,它可以记忆对象是否已经实例化了,在静态方法 getInstance() 中对这个变量进行判断,若没有实例化过就产生一个新的对象,如果已经实例化了则不再产生新的对象,仍然返回以前产生的实例。

【3】如何用java语言来实现该设计模式:以下采用2种方法来实现该模式。

第一种方法:用静态方法实现 Singleton 这种方法是使用静态方法来监视实例的创建。为了防止创建一个以上的实例,我们把构造器声明为 private。这样可以防止客户端程序员通过除由我们提供的方法之外的任意方式来创建一个实例。如果不把构造器声明为private,编译器则会创建一个默认的public的构造器。

具体实现的代码如下:

package com.andyidea.patterns.singleton;

public class Singleton {
	
	private static Singleton s;
	
	/**
	 * 把构造函数设置为private
	 */
	private Singleton(){
		
	}
	
	/**
	 * 实例化对象的唯一接口
	 * @return
	 */
	public static Singleton getInstance(){
		if(s == null){
			s = new Singleton();
		}
		return s;
	}

}
测试类代码如下:

package com.andyidea.patterns.client;

import com.andyidea.patterns.singleton.Singleton;

/**
 * 设计模式测试类
 * @author Andy.Chen
 *
 */
public class MainClient {

	public static void main(String[] args) {
	    Singleton s1 = Singleton.getInstance();
	    Singleton s2 = Singleton.getInstance();
	    
	    System.out.println("Welcome to Andy.Chen Blog!" +"\n" 
		           +"Singleton Patterns." +"\n"
		           +"-------------------------------");
	    
	    if (s1==s2)
	      System.out.println("s1 is the same instance with s2");
	    else
	      System.out.println("s1 is not the same instance with s2");
	}
}
程序运行的结果如下:

Welcome to Andy.Chen Blog!
Singleton Patterns.
-------------------------------
s1 is the same instance with s2
第二种方法: 以静态变量为标志实现 Singleton 在类中嵌入一个静态变量做为标志,每次都在进入构造器的时候进行检查。问题在于构造器没有返回类型,如果确定创建一个实例成功与否.一个方法是调用一个函数来检查创建是否成功,然后简单的返回一个来自静态变量的值,但是这样做是不优雅的,而且容易发生错误。比较好的做法是创建一个当创建了一个以上的实例时可以抛出异常的类,这个类仅仅是调用父类方法,好处是用了自己创建的异常类型,错误信息更加清晰。

具体实现的代码如下:

package com.andyidea.patterns.singleton;

public class Singleton {
	
	  static boolean instance_flag = false;
	  public Singleton() {
	    if (instance_flag)
	      throw new SingletonException("Only one instance allowed");
	    else
	      instance_flag = true;
	  }

}
异常类代码如下:

package com.andyidea.patterns.singleton;

/**
 * 异常类
 * @author Andy.Chen
 *
 */
public class SingletonException extends RuntimeException{

	public SingletonException(String exception){
		super(exception);
	}
}
测试类代码如下:

package com.andyidea.patterns.client;

import com.andyidea.patterns.singleton.Singleton;
import com.andyidea.patterns.singleton.SingletonException;

/**
 * 设计模式测试类
 * @author Andy.Chen
 *
 */
public class MainClient {

	public static void main(String[] args) {
		
	    System.out.println("Welcome to Andy.Chen Blog!" +"\n" 
        +"Singleton Patterns." +"\n"
        +"-------------------------------");
	    
	    Singleton s1, s2;
	    // create one incetance--this should always work
	    System.out.println("Creating one instance");
	    try {
	      s1 = new Singleton();
	    } catch (SingletonException e) {
	      System.out.println(e.getMessage());
	    }
	    // try to create another incetanced
	    System.out.println("Creating two instance");
	    try {
	      s2 = new Singleton();
	    } catch (SingletonException e) {
	      System.out.println(e.getMessage());
	    }
	}
}
运行结果如下:

Welcome to Andy.Chen Blog!
Singleton Patterns.
-------------------------------
Creating one instance
Creating two instance
Only one instance allowed
从输出的结果可以看出,第一个实例可以顺利创建,创建第二个实例的时候抛出了我们自定义的异常信息。


评论 6 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

cjjky

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值