Design Pattern: Registry of Singleton 模式
学习是分享和合作式的!
转载请注明出处:https://blog.csdn.net/wdzxl198/article/details/9248821;
文章摘自: https://www.riabook.cn/doc/designpattern/;
考虑使用 Singleton 模式 时拥有子类别的问题,在Singleton模式中的getInstance()通常是一个静态方法,不能在子类别中重新定义它,关于子类别实例的产生交由getInstance()来进行是最好的选择,例如:
1: public class Singleton {
2: private static Singleton instance = null;
3: private Singleton()
4: {
5: // ....
6:
7: }
8: public static Singleton getInstance()
9: {
10: if (instance == null)
11: {
12: //
13: getEnv表示系统环境变数
14:
15: String style = getEnv("style");
16:
17: if (style.equals("child1"))
18: instance = new ChildSingleton1();
19: else if(style.equals("child2r"))
20: instance = new ChildSingleton2();
21: else
22: instance = new Singleton();
23: }
24: return _instance;
25: }
26: // ....
27: }
上面这个程式片段改写自 Gof 书中关于Singleton的例子,并用Java实现;在书中指出,这个例子的缺点是每增加一个子类别,getInstance()就必须重新修改,这个问题在Java中可以使用Reflection机制来解决:
1: public class Singleton {
2: private static Singleton instance = null;
3: private Singleton() {
4: // ....
5: }
6: public static Singleton getInstance() {
7: if (instance == null) {
8: // getEnv表示环境变数
9: String style = getEnv("style");
10: try {
11: instance = (Singleton)
12: Class.forName(style).newInstance();
13: }
14: catch(Exception e) {
15: System.out.println(
16: "Sorry! No such class defined!");
17: }
18: }
19: return instance;
20: }
21: // ....
22: }
上面的方式使用了Java的Reflection机制,并透过环境变数设定要产生的子类Singleton,如果不使用Reflection的话,Gof 书中提出的改进方法是使用Registry of Singleton方法:
1: import java.util.*;
2: public class Singleton {
3: // 注册表,用于注册子类别物件
4: private static Map registry = new HashMap();
5: private static Singleton instance;
6: public static void register(
7: String name, Singleton singleton) {
8: registry.put(name, singleton);
9: }
10: public static Singleton getInstance() {
11: if (instance == null) {
12: // getEnv表示取得环境变数
13: String style = getEnv("style");
14: instance = lookup(style);
15: }
16: return instance;
17: }
18: protected static Singleton lookup(String name) {
19: return (Singleton) registry.get(name);
20: }
21: }
在Gof书中使用List来实现注册表,而在这边使用HasMap类别来实现,它是由Java SE所提供的;在父类别中提供一个register() 以注册Singleton的子类别所产生之实例,而注册的时机可以放在子类别的建构方法中加以实现,例如:
1: public class ChildSingleton1 extends Singleton {
2: public ChildSingleton1() {
3: // ....
4: // 注册子类别物件
5: register(getClass().getName(), this);
6: }
7: }
若要利用Singleton,则先使用这个子类别产生物件,这会向父类别注册物件,之后透过Singleton父类别来取得物件:
1: // 必须先启始这段注册程序
2: // 产生并注册ChildSingleton1物件
3: new ChildSingleton1();
4: // 产生并注册ChildSingleton2物件
5: new ChildSingleton2();
6:
7: // 注册完成,可以使用父类别来取得子类的Singleton
8: // 至于取回何哪一个,视您的环境变数设置决定
9: Singleton childSingleton = Singleton.getInstance();
10:
事实上Registry of Singleton的真正优点正在于此,您可以使用父类别来统一管理多个继承的子类别之Singleton实例,您可以在需要的时候再向父类别注册子类 Singleton,必要时随时调整传回的子类别Singleton。
Edit by Atlas
Time 2013/7/5 09:31
最后更新:2017-04-03 16:48:30