博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Design Pattern: Registry of Singleton 模式
阅读量:7225 次
发布时间:2019-06-29

本文共 3077 字,大约阅读时间需要 10 分钟。

一句话概括:您可以使用父类别来统一管理多个继承的子类别之Singleton实例,您可以在需要的时候再向父类别注册子类 Singleton,必要时随时调整传回的子类别Singleton。

考虑使用  时拥有子类别的问题,在Singleton模式中的getInstance()通常是一个静态方法,不能在子类别中重新定义它,关于子类别实例的产生交由getInstance()来进行是最好的选择,例如:

public class Singleton {    private static Singleton instance = null;    private 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;    }    // ....}

上面这个程式片段改写自 中关于Singleton的例子,并用Java实现;在书中指出,这个例子的缺点是每增加一个子类别,getInstance()就必须重新修改,这个问题在Java中可以使用Reflection机制来解决:

public class Singleton {    private static Singleton instance = null;    private 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;    }    // ....}

上面的方式使用了Java的Reflection机制,并透过环境变数设定要产生的子类Singleton,如果不使用Reflection的话,Gof 书中提出的改进方法是使用Registry of Singleton方法:

import java.util.*;public class Singleton {    // 注册表,用于注册子类别物件    private static Map registry = new HashMap();     private static Singleton instance;    public static void register(                 String name, Singleton singleton) {        registry.put(name, singleton);    }    public static Singleton getInstance() {        if (instance == null) {            // getEnv表示取得环境变数            String style = getEnv("style");            instance = lookup(style);        }        return instance;    }    protected static Singleton lookup(String name) {        return (Singleton) registry.get(name);    }}

在Gof书中使用List来实现注册表,而在这边使用HasMap类别来实现,它是由Java SE所提供的;在父类别中提供一个register() 以注册Singleton的子类别所产生之实例,而注册的时机可以放在子类别的建构方法中加以实现,例如:

public class ChildSingleton1 extends Singleton {    public ChildSingleton1() {        // ....        // 注册子类别物件        register(getClass().getName(), this);      }}

若要利用Singleton,则先使用这个子类别产生物件,这会向父类别注册物件,之后透过Singleton父类别来取得物件:

// 必须先启始这段注册程序 

// 产生并注册ChildSingleton1物件 
new ChildSingleton1(); 
// 产生并注册ChildSingleton2物件 
new ChildSingleton2();

// 注册完成,可以使用父类别来取得子类的Singleton 

// 至于取回何哪一个,视您的环境变数设置决定 
Singleton childSingleton = Singleton.getInstance();

这种方式的缺点是您必须在程式中启始一段程序,先向父类别注册子类的Singleton,之后才能透过父类别来取得指定的子类别Singleton实例, 好处是可以适用于没有Reflection机制的语言,如果您想要改变Singleton父类传回的子类Singleton,可以在上面的 Singleton类别中加入一个reset()方法,将instance设定为null,然后重新设定环境变数,之后再利用 Singleton父类的getInstance()方法重新取得注册表中的其它子类。 

事实上Registry of Singleton的真正优点正在于此,您可以使用父类别来统一管理多个继承的子类别之Singleton实例,您可以在需要的时候再向父类别注册子类 Singleton,必要时随时调整传回的子类别Singleton。

转载地址:http://xcufm.baihongyu.com/

你可能感兴趣的文章
案例分享〡三拾众筹持续交付开发流程支撑创新业务
查看>>
FreeWheel业务系统微服务化过程经验分享
查看>>
移动互联网下半场,iOS开发者如何“高薪”成长?
查看>>
Atlassian是怎样进行持续交付的?且听 Steve Smith一一道来
查看>>
Web Storage相关
查看>>
[PHP内核探索]PHP中的哈希表
查看>>
Apache-drill Architechture
查看>>
WordPress 5.2 Beta 3 发布,要求 PHP 5.6.20 以上版本
查看>>
通通连起来——无处不在的流
查看>>
互联网+时代,看云计算如何改变传统行业
查看>>
ZFS ARC & L2ARC zfs-$ver/module/zfs/arc.c
查看>>
c++类默认拷贝构造函数---浅复制
查看>>
2019年最火热的Golang项目
查看>>
可实现RSSD云硬盘120万IOPS的SPDK IO路径优化实践
查看>>
Vue项目部署遇到的坑(你肯定会遇到!)
查看>>
资源分享计划第三期 0511
查看>>
awk 文本处理
查看>>
【JSConf EU 2018】主题总结 (部分主题已有中文文章)
查看>>
JavaScript面向对象名词详解
查看>>
Java设计模式学习 - 责任链模式
查看>>