java

位置:IT落伍者 >> java >> 浏览文章

在Java中应用设计模式之Singleton


发布日期:2024年07月05日
 
在Java中应用设计模式之Singleton

基本概念

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

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

简单分析

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

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

  

: Singleton 模式结构

具体实施

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

用静态方法实现 Singleton

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

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

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 s = SingletongetInstance();

Singleton s = SingletongetInstance();

if (s==s)

Systemoutprintln

(s is the same instance with s);

else

Systemoutprintln

(s is not the same instance with s);

}

}

singletonTest运行结果是:

s is the same instance with s

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

以静态变量为标志实现 Singleton

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

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

class SingletonException extends RuntimeException

{

public SingletonException(String s)

{

super(s);

}

}

class Singleton

{

static boolean instance_flag = false;

// true if instance

public Singleton()

{

if (instance_flag)

throw new SingletonException

(Only one instance allowed);

else

instance_flag = true;

// set flag for instance

}

}

// 测试类

public class singletonTest

{

static public void main(String argv[])

{

Singleton s s;

// create one

incetancethis should always work

Systemoutprintln

(Creating one instance);

try {

s = new Singleton();

} catch (SingletonException e)

{

Systemoutprintln(egetMessage());

}

// try to create another

spooler should fail

Systemoutprintln

(Creating two instance);

try {

s = new Singleton();

} catch (SingletonException e)

{

Systemoutprintln(egetMessage());

}

}

}

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 实例               

上一篇:Java包含一个非常简单的享元模式

下一篇:谈谈Java加密技术(六)