快速业务通道

在Java中应用设计模式之Singleton - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-24

在Java中应用设计模式之Singleton

时间:2010-07-08

基本概念

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

再举个例子,集合中的 set 中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到 set,它只接受一个实例。JDK中正式运用了Singleton模式来实现 set 的这一特性,大家可以查看java.util.Collections里的内部静态类SingletonSet的原代码。其实Singleton是最简单但也是应用最广泛的模式之一,在 JDK 中随处可见。

简单分析

为了实现 Singleton 模式,我们需要的是一个静态的变量,能够在不创建对象的情况下记忆是否已经产生过实例了。静态变量或静态方法都可以在不产生具体实例的情况下直接调用,这样的变量或方法不会因为类的实例化而有所改变。

在图1的结构中可以看到,uniqueInstance 就是这个独立的静态变量,它可以记忆对象是否已经实例化了,在静态方法 Instance 中对这个变量进行判断,若没有实例化过就产生一个新的对象,如果已经实例化了则不再产生新的对象,仍然返回以前产生的实例。

在Java中应用设计模式之Singleton - 编程入门网

图1: Singleton 模式结构

具体实施

实现 Singleton 模式的办法通常有三种。

一、用静态方法实现 Singleton

这种方法是使用静态方法来监视实例的创建。为了防止创建一个以上的实例,我们最好把构造器声明为 private。

这样可以防止客户程序员通过除由我们提供的方法之外的任意方式来创建一个实例,如果不把构造器声明为private,编译器就会自作聪明的自动同步一个默认的friendly构造器。这种实现方法是最常见的,也就是图1中结构的标准实现。

public class Singleton { private static Singleton s; private Singleton() { }; /** * Class method to access the singleton instance of the class。 */ public static Singleton getInstance() { if (s == null) s = new Singleton(); return s; } } // 测试类 class singletonTest { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); 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"); } }

singletonTest运行结果是:

s1 is the same instance with s2

这证明我们只创建了一个实例.

在Java中应用设计模式之Singleton(2)

时间:2010-07-08

二、以静态变量为标志实现 Singleton

在类中嵌入一个静态变量做为标志,每次都在进入构造器的时候进行检查。

问题在于构造器没有返回类型,如果确定创建一个实例成功与否。---www.bianceng.cn。一个方法是调用一个函数来检查创建是否成功,然后简单的返回一个来自静态变量的值,但是这样做是不优雅的,而且容易发生错误。比较好的做法是创建一个当创建了一个以上的实例时可以抛出异常的类,这个类仅仅是调用父类方法,好处是用了自己命名的异常类型,错误信息更加清晰:

class SingletonException extends RuntimeException { public SingletonException(String s) { super(s); } } class Singleton { static boolean instance_flag = false; // true if 1 instance public Singleton() { if (instance_flag) throw new SingletonException ("Only one instance allowed"); else instance_flag = true; // set flag for 1 instance } } // 测试类 public class singletonTest { static public void main(String argv[]) { 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 spooler --should fail System.out.println ("Creating two instance"); try { s2 = new Singleton(); } catch (SingletonException e) { System.out.println(e.getMessage()); } } }

singletonTest运行结果是:

Creating one instance Creating two instance Only one instance allowed

可以看出,第一个实例顺利创建,第二个实例创建实抛出了我们自定义的异常。

三、用注册器机制来创建 Singleton

首先用集合中的Hashtable 和Enumeration来实现addItem(Object key, Object value),getItem(Object key),removeItem(Object key)等方法实现一个管理器,将key和value一一关联起来,客户程序员创建实例前首先用addItem方法进行注册,再用getItem方法获取实例。

Hashtable中的key是唯一的,从而保证创建的实例是唯一的,具体实现限于篇幅不再细说,在Prototype模型的应用一文中我将会给出一个实现注册器的代码。用注册器机制来创建 Singleton模式的好处是易于管理,可以同时控制多个不同类型的Singleton 实例。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号