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

 

【1】基本概念

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

【2】简单分析

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


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

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

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

具体实现的代码如下:

  1. <span style="font-size:16px;">package com.andyidea.patterns.singleton;
  2. public class Singleton {
  3. private static Singleton s;
  4. /**
  5. * 把构造函数设置为private
  6. */
  7. private Singleton(){
  8. }
  9. /**
  10. * 实例化对象的唯一接口
  11. * @return
  12. */
  13. public static Singleton getInstance(){
  14. if(s == null){
  15. s = new Singleton();
  16. }
  17. return s;
  18. }
  19. }</span>
测试类代码如下:

  1. <span style="font-size:16px;">package com.andyidea.patterns.client;
  2. import com.andyidea.patterns.singleton.Singleton;
  3. /**
  4. * 设计模式测试类
  5. * @author Andy.Chen
  6. *
  7. */
  8. public class MainClient {
  9. public static void main(String[] args) {
  10. Singleton s1 = Singleton.getInstance();
  11. Singleton s2 = Singleton.getInstance();
  12. System.out.println("Welcome to Andy.Chen Blog!" +"\n"
  13. +"Singleton Patterns." +"\n"
  14. +"-------------------------------");
  15. if (s1==s2)
  16. System.out.println("s1 is the same instance with s2");
  17. else
  18. System.out.println("s1 is not the same instance with s2");
  19. }
  20. }</span>
程序运行的结果如下:

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

具体实现的代码如下:

  1. <span style="font-size:16px;">package com.andyidea.patterns.singleton;
  2. public class Singleton {
  3. static boolean instance_flag = false;
  4. public Singleton() {
  5. if (instance_flag)
  6. throw new SingletonException("Only one instance allowed");
  7. else
  8. instance_flag = true;
  9. }
  10. }</span>
异常类代码如下:

  1. <span style="font-size:16px;">package com.andyidea.patterns.singleton;
  2. /**
  3. * 异常类
  4. * @author Andy.Chen
  5. *
  6. */
  7. public class SingletonException extends RuntimeException{
  8. public SingletonException(String exception){
  9. super(exception);
  10. }
  11. }</span>
测试类代码如下:

  1. <span style="font-size:16px;">package com.andyidea.patterns.client;
  2. import com.andyidea.patterns.singleton.Singleton;
  3. import com.andyidea.patterns.singleton.SingletonException;
  4. /**
  5. * 设计模式测试类
  6. * @author Andy.Chen
  7. *
  8. */
  9. public class MainClient {
  10. public static void main(String[] args) {
  11. System.out.println("Welcome to Andy.Chen Blog!" +"\n"
  12. +"Singleton Patterns." +"\n"
  13. +"-------------------------------");
  14. Singleton s1, s2;
  15. // create one incetance--this should always work
  16. System.out.println("Creating one instance");
  17. try {
  18. s1 = new Singleton();
  19. } catch (SingletonException e) {
  20. System.out.println(e.getMessage());
  21. }
  22. // try to create another incetanced
  23. System.out.println("Creating two instance");
  24. try {
  25. s2 = new Singleton();
  26. } catch (SingletonException e) {
  27. System.out.println(e.getMessage());
  28. }
  29. }
  30. }</span>
运行结果如下:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值