`
369128396
  • 浏览: 83850 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

Registry of Singleton 模式(转)

    博客分类:
  • java
 
阅读更多
考虑使用 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;
    }

    // ....
}

上面这个程式片段改写自 Gof 书中关于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。
分享到:
评论

相关推荐

    【船级社】 NK Regulati the Classification and Registry of Ships 2023

    【船级社】 NK Regulations for the Classification and Registry of Ships 2023.pdf

    Java registry,com.ice.jni.registry

    Files contained in registry-3.1.3.jar: META-INF/MANIFEST.MF com.ice.jni.registry.RegMultiStringValue.class com.ice.jni.registry.RegBinaryValue.class com.ice.jni.registry.RegistryException.class ...

    Laravel开发-laravel-registry

    在Laravel框架中,"Registry"模式是一种设计模式的应用,它允许我们存储和管理应用程序的各种配置和服务。在 Laravel 的上下文中,"laravel-registry" 可能指的是一个用于增强框架内部服务容器功能的第三方扩展或者...

    Registry Workshop: Registry Workshop 2.5绿色版

    4. **安全模式**:该软件具备安全模式,可以防止非授权或误操作导致的系统不稳定。在修改敏感区域前,它会提示用户确认操作,降低出错风险。 5. **导出与导入**:Registry Workshop支持导出注册表项为.reg文件,...

    docker registry与registry-web端管理部署.docx

    讲述了如何部署registry、registry-web的部署,以及registry-web如何管理registry私库的镜像上传、下载的授权、镜像删除、用户管理

    java读写注册表jar包,com.ice.jni.registry

    META-INF/MANIFEST.MF com.ice.jni.registry.HexNumberFormat.class com.ice.jni.registry.NoSuchKeyException.class com.ice.jni.registry.NoSuchValueException.class com.ice.jni.registry.RegBinaryValue.class ...

    docker registry离线镜像

    docker官方镜像仓库registry离线包,使用docker load -i registry.tar

    RemoteRegistry服务修复

    远程注册表服务(Remote Registry)是Windows操作系统中的一个重要组件,主要功能是允许远程用户修改本地计算机的注册表设置。在日常的系统管理和网络维护中,这项服务对于远程诊断和修复问题,尤其是对于IT管理员和...

    docker registry私库与registry-web管理端部署.docx

    讲述了如何部署registry、registry-web的部署,registry-web是如何管理registry私库的镜像上传、下载的授权、镜像删除、用户管理,提供用户认证的

    registry.jar java读写注册表的开源库

    `registry.jar`是一个专门为Java设计的开源库,它允许开发者在Java应用程序中方便地访问和修改Windows注册表。这个库名为`registry3.1.3.jar`,包含了源代码,使得开发者可以深入理解其内部工作原理,同时也提供了`...

    7种单例模式

    单例模式是软件设计模式中的一种经典模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如控制共享资源、管理配置对象等。下面将详细介绍七种常见的单例模式实现...

    docker的registry镜像

    dockerhub经常访问不了,特地将registry下载到本地,供大家学习使用

    micrometer-registry-prometheus-1.8.2-API文档-中文版.zip

    赠送jar包:micrometer-registry-prometheus-1.8.2.jar 赠送原API文档:micrometer-registry-prometheus-1.8.2-javadoc.jar 赠送源代码:micrometer-registry-prometheus-1.8.2-sources.jar 包含翻译后的API文档...

    单例模式的要点及模式

    单例模式是软件设计模式中的一种经典模式,其核心思想在于限制类的实例化过程,确保在整个应用程序中只有一个实例存在。这种模式常用于管理共享资源,例如数据库连接、线程池或者全局配置等,以避免资源浪费和状态...

    kafka-schema-registry-client-6.2.2.jar

    Could not resolve dependencies for project org.apache.flink:flink-avro-confluent-registry:jar:1.15.3: Could not find artifact io.confluent:kafka-schema-registry-client:jar:6.2.2 in maven 安装本地...

    ORACLE SYS.DBMS_REGISTRY_SYS has errors

    标题中的问题“ORACLE SYS.DBMS_REGISTRY_SYS has errors”指的是在Oracle数据库系统中,系统包BODY `SYS.DBMS_REGISTRY_SYS` 出现错误,导致了一系列的PL/SQL调用失败。这种错误通常与数据库的元数据注册功能有关,...

    Windows Registry Forensics

    Windows Registry Forensics Advanced Digital Forensic Analysis of the Windows Registry Harlan Carvey brings readers an advanced book on Windows Registry. The first book of its kind EVER -- Windows ...

    registry-3.1.3jar包下载

    解决动态链接库ICE_JNIRegistry.dll位置放置问题,该jar包中已经...该压缩包中有regist.jar和registry源码,regist.jar是将registry-3.1.3的源码修改后重新编译的,不需要ICE_JNIRegistry.dll,直接调用regist.jar即可

Global site tag (gtag.js) - Google Analytics