设计模式之单例模式Singleton 详解和实例演示

来源:互联网 发布:周杰伦 双刀 知乎 编辑:程序博客网 时间:2024/06/01 10:48

使用情况:

一般当我们在程序只要生成一个类的实例时,我们就使用Singleton模式。

优点:

可控制实例数仅有一个,改进后可以控制实例的数量。

实现:

基本结构如下:

一个Simgleton的类中,一般包含如下几个关键点:

Pirvate 的本实例引用

Private 的够造方法

重写clone方法

程序模板如下:

package singleton;

/**

 *SimpleSingleton.java

 * Created on 7:06:43 PM Mar 1, 2009

 *@author Quasar063501

 *@version 0.1

 * 

 */

public class SimpleSingleton {

private static SimpleSingleton instance = null;

private SimpleSingleton() {

//只是为了在类的外部实例化

}

//synchronized防止多线程时竞争条件

public static synchronized SimpleSingleton getSingleton() {

if(instance == null) {

instance = new SimpleSingleton();

}

return instance;

}

//防止在“=”时和使用clone()时得到实例

public SimpleSingleton clone() throws CloneNotSupportedException{

throw new CloneNotSupportedException();

}

public void sayHello() {

System.out.println("Hello! I am "+getClass().getName()+".");

}

//用于测试,clone时抛出异常

// public static void main(String args[]) {

// SimpleSingleton s = SimpleSingleton.getSingleton();

// s.sayHello();

//// try {

//// SimpleSingleton s1 = s.clone();

//// s1.sayHello();

//// } catch (CloneNotSupportedException e) {

//// e.printStackTrace();

//// /**

////  * java.lang.CloneNotSupportedException

////          * at singleton.SimpleSingleton.clone(SimpleSingleton.java:28)

////          * at singleton.SimpleSingleton.main(SimpleSingleton.java:40)

////  */

//// }

// }

}

这是最简单的单例实现了,一般情况下,我们尽量使singleton的类没有子类,这样可以省去不少麻烦,不过,如果实现,也是可以的,但构造方法只能是protected的了。只能在包外保证单例。有三种方法,如下:

我们给出一种使用于没有反射机制的注册实现,其他的简要介绍。

1判断式

每次添加子类,必须修改父类的getInstance方法,不好!

public class Singleton {
    private static Singleton instance = null;
    protected Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        if (instance == null) {
            // getEnv表示系統環境變數
            String style = getEnv("style");

            if (style.equals("child1"))
                instance = new ChildSingleton1();
            else if (style.equals("child2r"))
                instance = new ChildSingleton2();
            else
                instance = new Singleton();
        }

        return _instance;
    }

    // ....
}

2反射式(只适用于java这种有反射机制的语言)

public class Singleton {
    private static Singleton instance = null;
    protected Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        if (instance == null) {
            // getEnv表示環境變數
            String style = getEnv("style");

            try {
                instance = (Singleton)
                          Class.forName(style).newInstance();
            }
            catch(Exception e) {
                System.out.println(
                   "Sorry! No such class defined!");
            }
        }

        return instance;
    }

    // ....
}

3具体实现的注册单例模式

子类的构造方法中,注册实例到map,在定义lookup方法,返回实例,具体代码如下:

父类:

package singleton;

import java.util.HashMap;

import java.util.Map;

/**

 *SimpleSingleton.java

 * Created on 7:06:43 PM Mar 1, 2009

 *@author Quasar063501

 *@version 0.1

 * 

 */

public class SimpleSingleton {

//用于储存singleton家族的一系列对象

private static Map<String, SimpleSingleton> instances= new HashMap();

private static SimpleSingleton instance = null;

protected SimpleSingleton() {

//保证包外单例

}

//synchronized防止多线程时竞争条件

public static synchronized SimpleSingleton getSingleton(String name) {

if(instance == null) {

instance = lookup(name);

}

return instance;

}

//防止在“=”时和使用clone()时得到实例

public SimpleSingleton clone() throws CloneNotSupportedException{

throw new CloneNotSupportedException();

}

//用于注册

public static void register(String name, SimpleSingleton instance) {

instances.put(name, instance);

}

//用于查找

private static SimpleSingleton lookup(String name) {

return instances.get(name);

}

public void sayHello() {

System.out.println("Hello! I am "+getClass().getName()+".");

}

}

俩个子类:

package singleton;

/**

 *Singleton1.java

 * Created on 7:22:25 PM Mar 1, 2009

 *@author Quasar063501

 *@version 0.1

 * 

 */

public class Singleton1 extends SimpleSingleton{

 public Singleton1() {

register(getClass().getName(), this);

}

}

package singleton;

/**

 *Singleton2.java

 * Created on 7:24:51 PM Mar 1, 2009

 *@author Quasar063501

 *@version 0.1

 * 

 */

public class Singleton2 extends SimpleSingleton{

}

测试类:

package testsingle;

import singleton.SimpleSingleton;

import singleton.Singleton1;

import singleton.Singleton2;

/**

 *TestSingle.java

 * Created on 8:03:14 PM Mar 1, 2009

 *@author Quasar063501

 *@version 0.1

 * 

 */

public class TestSingle {

public static void main(String[] args) {

// SimpleSingleton s = new SimpleSingleton();

// s.sayHello();

//生成并注册

        new Singleton1();

//通过父类得到子类

SimpleSingleton s1 = SimpleSingleton.getSingleton("singleton.Singleton1");

s1.sayHello();

new Singleton2();

SimpleSingleton s2 = SimpleSingleton.getSingleton("singleton.Singleton2");

s2.sayHello();

/**

 * 输出:  Hello! I am singleton.Singleton1.

 *   Hello! I am singleton.Singleton1.

 * 保证了单例!

 */

}

}

后续将会更详细的讲解单例!

原创粉丝点击